Skip to content

Commit 10f019d

Browse files
committed
Set basePath on swagger.json when serving under OpenWhisk
We need to setup the proper base path when we are running under OpenWhisk, as the OpenAPI spec states that all URLs are constructed using basePath (if exists) or otherwise they are absolute urls. Since we are running as Web actions in OW, we need to set the basePath to the actual action path.
1 parent d84889b commit 10f019d

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

deepaas/api/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555

5656
async def get_app(swagger=True, doc="/ui", prefix="",
57-
static_path="/static/swagger",
57+
static_path="/static/swagger", base_path="",
5858
enable_train=True, enable_predict=True):
5959
"""Get the main app."""
6060
global APP
@@ -120,6 +120,7 @@ async def get_app(swagger=True, doc="/ui", prefix="",
120120
"description": "API documentation",
121121
"url": "https://deepaas.readthedocs.org/",
122122
},
123+
basePath=base_path,
123124
version=deepaas.__version__,
124125
url="/swagger.json",
125126
swagger_path=doc if doc else None,

deepaas/openwhisk/proxy.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,24 @@
2929
from deepaas import api
3030
from deepaas.openwhisk import handle
3131

32+
cli_opts = [
33+
cfg.StrOpt('base-openwhisk-path',
34+
default='/api/v1/web',
35+
help="""
36+
Base path where OpenWhisk web actions are served.
37+
38+
This option is being used to build the base path for the swagger.json file
39+
that is served as part of the OpenWhisk action. By default this configuration
40+
variable points to "/api/v1/web/". We append to this variable the name of the
41+
action, so that the swagger.json contains the correct basePath.
42+
"""),
43+
]
44+
3245
CONF = cfg.CONF
46+
CONF.register_cli_opts(cli_opts)
3347

3448
LOG_SENTINEL = 'XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX'
3549

36-
3750
routes = web.RouteTableDef()
3851

3952
APP = None
@@ -46,11 +59,30 @@
4659
async def init(request):
4760
global APP
4861

62+
try:
63+
message = await request.json()
64+
except Exception as e:
65+
return error_bad_request(msg="Error: {}".format(e))
66+
67+
if message and not isinstance(message, dict):
68+
return error_bad_request()
69+
else:
70+
args = message.get('value', {}) if message else {}
71+
if not isinstance(args, dict):
72+
return error_bad_request()
73+
env = args.get('env', {})
74+
if not isinstance(env, dict):
75+
return error_bad_request()
76+
77+
base = CONF.base_openwhisk_path
78+
action_name = env.get('__OW_ACTION_NAME', '')
79+
base_path = "{}{}".format(base, action_name)
80+
4981
try:
5082
if APP is None:
5183
APP = await api.get_app(swagger=True,
5284
doc=False,
53-
prefix=".",
85+
base_path=base_path,
5486
enable_train=False)
5587
return web.Response(text="OK", status=200)
5688
except Exception as e:

deepaas/tests/test_openwhisk.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ def setUp(self):
4949

5050
proxy.APP = None
5151

52+
async def init_action(self):
53+
data = {
54+
"value": {
55+
"env": {
56+
"__OW_ACTION_NAME": "/foo/bar",
57+
}
58+
}
59+
}
60+
return await self.client.post("/init", json=data)
61+
5262
def get_wsk_args(self, path):
5363
return {
5464
"value": {
@@ -65,7 +75,7 @@ def assertJSON(self, expected, actual):
6575

6676
@test_utils.unittest_run_loop
6777
async def test_init(self):
68-
ret = await self.client.post("/init")
78+
ret = await self.init_action()
6979
self.assertEqual(200, ret.status)
7080
txt = await ret.text()
7181
self.assertEqual("OK", txt)
@@ -78,7 +88,7 @@ def test_mock(self):
7888
m_get_app.side_effect = Exception("K-Boom")
7989

8090
async def test_init_failure():
81-
ret = await self.client.post("/init")
91+
ret = await self.init_action()
8292
self.assertEqual(500, ret.status)
8393
self.assertDictEqual(
8494
{'error': 'Internal error. K-Boom'},
@@ -96,15 +106,15 @@ async def do_test():
96106

97107
def test_run_no_data(self):
98108
async def do_test():
99-
ret = await self.client.post("/init")
109+
ret = await self.init_action()
100110
ret = await self.client.post("/run")
101111
self.assertEqual(400, ret.status)
102112
self.loop.run_until_complete(do_test())
103113

104114
def test_run_versions(self):
105115
async def do_test():
106116
data = self.get_wsk_args("/")
107-
ret = await self.client.post("/init")
117+
ret = await self.init_action()
108118
ret = await self.client.post("/run", json=data)
109119
body = copy.deepcopy(fake_responses.versions)
110120
# Terrible
@@ -120,7 +130,7 @@ async def do_test():
120130
def test_run_version_v2(self):
121131
async def do_test():
122132
data = self.get_wsk_args("/v2/")
123-
ret = await self.client.post("/init")
133+
ret = await self.init_action()
124134
ret = await self.client.post("/run", json=data)
125135
body = fake_responses.v2_version
126136
resp = {
@@ -134,7 +144,7 @@ async def do_test():
134144
def test_run_models(self):
135145
async def do_test():
136146
data = self.get_wsk_args("/v2/models")
137-
ret = await self.client.post("/init")
147+
ret = await self.init_action()
138148
ret = await self.client.post("/run", json=data)
139149
body = fake_responses.models_meta
140150
resp = {
@@ -148,7 +158,7 @@ async def do_test():
148158
def test_run_models_deepaas(self):
149159
async def do_test():
150160
data = self.get_wsk_args("/v2/models/deepaas-test")
151-
ret = await self.client.post("/init")
161+
ret = await self.init_action()
152162
ret = await self.client.post("/run", json=data)
153163
body = fake_responses.deepaas_test_meta
154164
resp = {

0 commit comments

Comments
 (0)