-
Notifications
You must be signed in to change notification settings - Fork 26
Client WebApp API #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
b2ee515
152347c
1105823
455cdf9
54ef4cf
28bf8d7
53cd5be
8f37d10
9efdcb4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import sys | ||
from .future import DSSFuture | ||
|
||
if sys.version_info >= (3,0): | ||
import urllib.parse | ||
dku_quote_fn = urllib.parse.quote | ||
else: | ||
import urllib | ||
dku_quote_fn = urllib.quote | ||
|
||
|
||
class DSSWebApp(object): | ||
""" | ||
A handle to manage a webapp | ||
""" | ||
def __init__(self, client, project_key, webapp_id, state=None): | ||
"""Do not call directly, use :meth:`dataikuapi.dss.project.DSSProject.get_webapps`""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo |
||
self.client = client | ||
self.project_key = project_key | ||
self.webapp_id = webapp_id | ||
self.state = state | ||
|
||
def get_state(self): | ||
apichery marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
Return the state of the webapp | ||
|
||
:return: the state of the webapp | ||
""" | ||
return self.state | ||
|
||
def stop_backend(self): | ||
""" | ||
Stop a webapp | ||
""" | ||
self.client._perform_empty("PUT", "/projects/%s/webapps/%s/stop-backend" % (self.project_key, self.webapp_id)) | ||
return | ||
|
||
def restart_backend(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While this corresponds to what the API really does, the fact that there is a "restart" method but no "start" method could be confusing. Not sure what the best to do is here. Maybe call the method |
||
""" | ||
Restart a webapp | ||
""" | ||
apichery marked this conversation as resolved.
Show resolved
Hide resolved
|
||
future = self.client._perform_json("PUT", "/projects/%s/webapps/%s/restart-backend" % (self.project_key, self.webapp_id)) | ||
return DSSFuture(self.client, future["jobId"]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use DSSFuture.from_resp which properly handles the case where the future instantly succeeded or failed (here, it will do KeyError on jobId |
||
|
||
def get_definition(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "get_definition" is the legacy naming for legacy methods that return a dict. Modern methods that return settings must be called get_settings and return an object called XXXSettings |
||
""" | ||
Get a webapp definition | ||
:returns: a handle to manage the webapp definition | ||
:rtype: :class:`dataikuapi.dss.webapp.DSSWebAppDefinition` | ||
""" | ||
definition = self.client._perform_json("GET", "/projects/%s/webapps/%s" % (self.project_key, self.webapp_id)) | ||
return DSSWebAppDefinition(self.client, self.project_key, self.webapp_id, definition) | ||
|
||
apichery marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
class DSSWebAppDefinition(object): | ||
""" | ||
A handle to manage a WebApp definition | ||
""" | ||
def __init__(self, client, project_key, webapp_id, definition): | ||
"""Do not call directly, use :meth:`dataikuapi.dss.webapp.DSSWebApp.get_definition`""" | ||
self.client = client | ||
self.project_key = project_key | ||
self.webapp_id = webapp_id | ||
self.definition = definition | ||
|
||
def get_definition(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this would be webapp.get_definition().get_definition() :) Standard practice is to call this method get_raw so it will be webapp.get_settings().get_raw() |
||
""" | ||
Get the definition | ||
|
||
|
||
:returns: the definition of the webapp | ||
""" | ||
return self.definition | ||
|
||
def set_definition(self, definition): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, no set function on a "modern" settings object. It's modification in place. |
||
""" | ||
Set the definition | ||
|
||
:param definition : the definition of the webapp | ||
""" | ||
self.definition = definition | ||
|
||
def save(self): | ||
""" | ||
Save the current webapp definition and update | ||
:returns: a wrapper to a future | ||
apichery marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
future = self.client._perform_json("PUT", "/projects/%s/webapps/%s" % (self.project_key, self.webapp_id), body=self.definition) | ||
self.definition = self.client._perform_json("GET", "/projects/%s/webapps/%s" % (self.project_key, self.webapp_id)) | ||
return future | ||
spicquenot marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
from time import sleep | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would remove this test class as it cannot be run automatically There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Talk with @Basharsh96 first :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made a copy of the test and I'll add it later to the tests in the CI pipeline I'm working on. Thank you, you can safely remove it 😊 |
||
from dataikuapi.dssclient import DSSClient | ||
from dataikuapi.dss.project import DSSProject | ||
from dataikuapi.dss.webapp import DSSWebApp | ||
from nose.tools import ok_ | ||
from nose.tools import eq_ | ||
|
||
host="http://localhost:8083" | ||
apiKey="CMZBjFkUgcDh08S3awoPyVIweBelxPjy" | ||
testProjectKey="WEBAPPS" | ||
testWebAppPythonId="VCMN2ra" | ||
|
||
|
||
def remove_key(d, key): | ||
r = dict(d) | ||
del r[key] | ||
return r | ||
|
||
|
||
class WebappApi_tests(object): | ||
|
||
def __init__(self): | ||
self.client = None | ||
self.project = None; | ||
|
||
def setUp(self): | ||
self.client = DSSClient(host, apiKey) | ||
self.project = DSSProject(self.client, testProjectKey) | ||
|
||
def list_webapps_test(self): | ||
webapps = self.project.list_webapps(); | ||
ok_(len(webapps) > 0) | ||
|
||
def get_python_webapp_test(self): | ||
webapp = self.project.get_webapp(testWebAppPythonId) | ||
ok_(webapp is not None) | ||
|
||
def get_definition_test(self): | ||
webapp = self.project.get_webapp(testWebAppPythonId) | ||
definition = webapp.get_definition() | ||
ok_(definition is not None) | ||
eq_(definition.webapp_id, testWebAppPythonId) | ||
eq_(definition.get_definition()["id"], testWebAppPythonId) | ||
|
||
def update_python_webapp_test(self): | ||
webapp = self.project.get_webapp(testWebAppPythonId) | ||
definition = webapp.get_definition() | ||
old_def = dict(definition.get_definition()) | ||
future = definition.save() | ||
ok_(future is not None) | ||
eq_(remove_key(definition.get_definition(), "versionTag"), remove_key(old_def, "versionTag")) | ||
eq_(definition.get_definition()["versionTag"]["versionNumber"], old_def["versionTag"]["versionNumber"] + 1) | ||
|
||
def restart_backend_test(self): | ||
""" | ||
WARNING: you should manually stop the backend before this test | ||
""" | ||
filtered_webapps = [w for w in self.project.list_webapps() if w.webapp_id == testWebAppPythonId] | ||
ok_(not filtered_webapps[0].get_state()["backendRunning"], "The backend should be stopped before the test") | ||
future = filtered_webapps[0].restart_backend() | ||
future.wait_for_result() | ||
filtered_webapps = [w for w in self.project.list_webapps() if w.webapp_id == testWebAppPythonId] | ||
ok_(filtered_webapps[0].get_state()["backendRunning"]) | ||
|
||
def stop_backend_test(self): | ||
""" | ||
WARNING: you should manually start the backend before this test | ||
""" | ||
filtered_webapps = [w for w in self.project.list_webapps() if w.webapp_id == testWebAppPythonId] | ||
ok_(filtered_webapps[0].get_state()["backendRunning"],"The backend should be started before the test") | ||
filtered_webapps[0].stop_backend() | ||
sleep(2) | ||
filtered_webapps = [w for w in self.project.list_webapps() if w.webapp_id == testWebAppPythonId] | ||
ok_(not filtered_webapps[0].get_state()["backendRunning"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adopt the newer standard of returning either listitem or object. See list_scenarios for an up-to-date example. This allows basic listing with a single API call instead of N+1
Provide properties on the core things in the DSSWebAppListItem