Skip to content

Commit 52addd9

Browse files
committed
now handling known /solve uri better
1 parent 85d6f54 commit 52addd9

File tree

3 files changed

+49
-13
lines changed

3 files changed

+49
-13
lines changed

src/ghhops-server-py/examples/app.py

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ def update():
2020
return "Update example!"
2121

2222

23+
# /solve is a builtin method and can not be overrriden
24+
@app.route("/solve", methods=["GET", "POST"])
25+
def solve():
26+
return "Oh oh! this should not happen!"
27+
28+
2329
@hops.component(
2430
"/binmult",
2531
inputs=[hs.HopsNumber("A"), hs.HopsNumber("B")],

src/ghhops-server-py/ghhops_server/base.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,28 @@
1818
class HopsBase:
1919
"""Base class for all Hops middleware implementations"""
2020

21+
SOLVE_URI = "/solve"
22+
23+
ERROR_PAGE_405 = """<!doctype html>
24+
<html lang=en>
25+
<title>405 Method Not Allowed</title>
26+
<h1>Method Not Allowed</h1>
27+
<p>The method is not allowed for the requested URL.</p>"""
28+
2129
def __init__(self, app):
2230
self.app = app
2331
# components dict store each components two times under
2432
# two keys get uri and solve uri, for faster lookups in query and solve
2533
# it is assumed that uri and solve uri and both unique to the component
2634
self._components: dict[str, HopsComponent] = {}
2735

28-
def contains(self, uri):
36+
def handles(self, uri):
37+
return uri == HopsBase.SOLVE_URI or uri in self._components
38+
39+
def is_solve_uri(self, uri):
40+
return uri == HopsBase.SOLVE_URI
41+
42+
def is_comp_uri(self, uri):
2943
return uri in self._components
3044

3145
def query(self, uri) -> Tuple[bool, str]:
@@ -53,7 +67,7 @@ def solve(self, uri, payload) -> Tuple[bool, str]:
5367
return False, self._return_with_err("Nothing to solve on root")
5468

5569
# FIXME: remove support for legacy solve behaviour
56-
elif uri == "/solve":
70+
elif uri == HopsBase.SOLVE_URI:
5771
data = json.loads(payload)
5872
comp_uri = data["pointer"]
5973
if not comp_uri.startswith("/"):
@@ -84,6 +98,11 @@ def _return_with_err(self, err_msg, res_dict=None):
8498

8599
return json.dumps(err_res, cls=_HopsEncoder)
86100

101+
def _return_method_not_allowed(self, environ, start_response):
102+
response = self._prep_response(405, "Method Not Allowed")
103+
response.data = HopsBase.ERROR_PAGE_405.encode(encoding="utf_8")
104+
return response(environ, start_response)
105+
87106
def _get_all_comps_data(self):
88107
# return json formatted string of all components metadata
89108
return json.dumps(list(self._components.values()), cls=_HopsEncoder)

src/ghhops-server-py/ghhops_server/middlewares/hopsflask.py

+22-11
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@
77
class HopsFlask(base.HopsBase):
88
"""Hops Middleware for Flask"""
99

10-
ERROR_PAGE_405 = """<!doctype html>
11-
<html lang=en>
12-
<title>405 Method Not Allowed</title>
13-
<h1>Method Not Allowed</h1>
14-
<p>The method is not allowed for the requested URL.</p>"""
15-
1610
def __init__(self, flask_app):
1711
# keep a ref to original flask app
1812
super(HopsFlask, self).__init__(flask_app)
@@ -36,18 +30,36 @@ def __call__(self, environ, start_response):
3630
comp_uri = request.path
3731

3832
# if uri is registered on the hops app
39-
if self.contains(comp_uri):
33+
if self.handles(comp_uri):
4034
if method == "GET":
41-
# if component exists
35+
# if calling GET /solve, respond 405
36+
if self.is_solve_uri(comp_uri):
37+
return self._return_method_not_allowed(
38+
environ,
39+
start_response
40+
)
41+
42+
# if component exists, return component data
4243
res, results = self.query(uri=comp_uri)
4344
if res:
4445
response = self._prep_response()
4546
response.data = results
47+
48+
# otherwise return 404
4649
else:
4750
response = self._prep_response(404, "Unknown URI")
51+
4852
return response(environ, start_response)
4953

5054
elif method == "POST":
55+
# if POST on component uri, return 405
56+
if self.is_comp_uri(comp_uri):
57+
return self._return_method_not_allowed(
58+
environ,
59+
start_response
60+
)
61+
62+
# otherwise try to solve with payload
5163
data = request.data
5264
res, results = self.solve(uri=comp_uri, payload=data)
5365
if res:
@@ -56,12 +68,11 @@ def __call__(self, environ, start_response):
5668
else:
5769
response = self._prep_response(404, "Execution Error")
5870
response.data = results.encode(encoding="utf_8")
71+
5972
return response(environ, start_response)
6073

6174
# respond with 405 if method is not valid
62-
response = self._prep_response(405, "Method Not Allowed")
63-
response.data = HopsFlask.ERROR_PAGE_405.encode(encoding="utf_8")
64-
return response(environ, start_response)
75+
return self._return_method_not_allowed(environ, start_response)
6576

6677
# otherwise ask wapped app to process the call
6778
return self.wsgi_app(environ, start_response)

0 commit comments

Comments
 (0)