From d80d24832d0c83b345e1fa3fa5da7ffd5a8d7993 Mon Sep 17 00:00:00 2001 From: Alvaro Lopez Garcia Date: Tue, 19 Mar 2024 11:13:18 +0100 Subject: [PATCH] feat: add ability to setup base path to serve the API from a custom path Fixes #111 --- deepaas/cmd/run.py | 12 ++++++++ deepaas/tests/test_v2_api.py | 53 ++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/deepaas/cmd/run.py b/deepaas/cmd/run.py index b5532224..8f953d27 100644 --- a/deepaas/cmd/run.py +++ b/deepaas/cmd/run.py @@ -45,6 +45,17 @@ The DEEPaaS API service listens on this port number for incoming requests. +""", + ), + # Allow to define base path for the API + cfg.StrOpt( + "base-path", + default="", + help=""" +Base path for the API. This is useful when the API is served behind a +reverse proxy that is not at the root of the domain. For example, if +the API is served at https://example.com/deepaas, then the base path +should be set to /deepaas. Defaults to the root of the domain. """, ), ] @@ -95,6 +106,7 @@ def main(): enable_doc=CONF.doc_endpoint, enable_train=CONF.train_endpoint, enable_predict=CONF.predict_endpoint, + base_path=CONF.base_path, ) web.run_app( app, diff --git a/deepaas/tests/test_v2_api.py b/deepaas/tests/test_v2_api.py index 7ad89df4..b6cad651 100644 --- a/deepaas/tests/test_v2_api.py +++ b/deepaas/tests/test_v2_api.py @@ -164,6 +164,59 @@ async def test_not_found(self): self.assertEqual(404, ret.status) +class TestApiV2CusomBasePath(base.TestCase): + async def get_application(self): + app = web.Application(debug=True) + app.middlewares.append(web.normalize_path_middleware()) + + deepaas.model.v2.register_models(app) + + v2app = v2.get_app(base_path="/custom") + app.add_subapp("/v2", v2app) + + return app + + def setUp(self): + super(TestApiV2CusomBasePath, self).setUp() + + self.maxDiff = None + + self.flags(debug=True) + + def assert_ok(self, response): + self.assertIn(response.status, [200, 201]) + + async def test_predict_data(self): + f = six.BytesIO(b"foo") + ret = await self.client.post( + "/custom/v2/models/deepaas-test/predict/", + data={"data": (f, "foo.txt"), "parameter": 1}, + ) + json = await ret.json() + self.assertEqual(200, ret.status) + self.assertDictEqual(fake_responses.deepaas_test_predict, json) + + async def test_train(self): + ret = await self.client.post( + "/custom/v2/models/deepaas-test/train/", data={"sleep": 0} + ) + self.assertEqual(200, ret.status) + json = await ret.json() + json.pop("date") + self.assertDictEqual(fake_responses.deepaas_test_train, json) + + async def test_get_metadata(self): + meta = fake_responses.models_meta + + ret = await self.client.get("/custom/v2/models/") + self.assert_ok(ret) + self.assertDictEqual(meta, await ret.json()) + + ret = await self.client.get("/custom/v2/models/deepaas-test/") + self.assert_ok(ret) + self.assertDictEqual(meta["models"][0], await ret.json()) + + class TestApiV2(base.TestCase): async def get_application(self): app = web.Application(debug=True)