Skip to content

Commit 56a22bf

Browse files
author
Joel Collins
committed
Improved HTTP form builder
1 parent 0d6af5f commit 56a22bf

File tree

1 file changed

+79
-26
lines changed

1 file changed

+79
-26
lines changed

src/labthings/td.py

Lines changed: 79 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,46 @@
1313
from .utilities import get_docstring, snake_to_camel
1414

1515

16-
def build_forms_for_view(rules: list, view: View, op: list):
17-
"""Build a W3C form description for a particular View
16+
def view_to_thing_action_forms(rules: list, view: View):
17+
"""Build a W3C form description for an ActionView
1818
1919
Args:
2020
rules (list): List of Flask rules
2121
view (View): View class
22-
op (list): List of Form operations
2322
2423
Returns:
2524
[dict]: Form description
2625
"""
2726
forms = []
28-
prop_urls = [rule_to_path(rule) for rule in rules]
2927

30-
content_type = getattr(view, "content_type", None) or "application/json"
28+
# HTTP invokeaction requires POST method
29+
if hasattr(view, "post"):
30+
prop_urls = [rule_to_path(rule) for rule in rules]
31+
32+
# Get input content_type
33+
content_type = getattr(view, "content_type", "application/json")
34+
35+
# See if the action has an unusual 200 response
36+
responses = view.get_responses()
37+
response_content_type = "application/json" # Default assumed content_type
3138

32-
for url in prop_urls:
33-
forms.append({"op": op, "href": url, "contentType": content_type})
39+
for response_code in (200, 201):
40+
if response_code in responses and responses[response_code].get(
41+
"content_type"
42+
):
43+
response_content_type = responses[response_code].get("content_type")
44+
break
45+
46+
for url in prop_urls:
47+
forms.append(
48+
{
49+
"op": ["invokeaction"],
50+
"htv:methodName": "POST",
51+
"href": url,
52+
"contentType": content_type,
53+
"response": {"contentType": response_content_type},
54+
}
55+
)
3456

3557
return forms
3658

@@ -41,35 +63,66 @@ def view_to_thing_property_forms(rules: list, view: View):
4163
Args:
4264
rules (list): List of Flask rules
4365
view (View): View class
44-
op (list): List of Form operations
4566
4667
Returns:
4768
[dict]: Form description
4869
"""
49-
readable = hasattr(view, "post") or hasattr(view, "put") or hasattr(view, "delete")
50-
writeable = hasattr(view, "get")
70+
forms = []
5171

52-
op = []
53-
if readable:
54-
op.append("readproperty")
55-
if writeable:
56-
op.append("writeproperty")
72+
# Get basic information
73+
prop_urls = [rule_to_path(rule) for rule in rules]
5774

58-
return build_forms_for_view(rules, view, op=op)
75+
# Get input content_type
76+
content_type = getattr(view, "content_type", "application/json")
5977

78+
# See if the property has an unusual 201 response
79+
responses = view.get_responses()
80+
response_content_type = "application/json" # Default assumed content_type
6081

61-
def view_to_thing_action_forms(rules: list, view: View):
62-
"""Build a W3C form description for an ActionView
82+
for response_code in (201, 200):
83+
if response_code in responses and responses[response_code].get("content_type"):
84+
response_content_type = responses[response_code].get("content_type")
85+
break
6386

64-
Args:
65-
rules (list): List of Flask rules
66-
view (View): View class
67-
op (list): List of Form operations
87+
# HTTP readproperty requires GET method
88+
if hasattr(view, "get"):
89+
for url in prop_urls:
90+
forms.append(
91+
{
92+
"op": ["readproperty"],
93+
"htv:methodName": "GET",
94+
"href": url,
95+
"contentType": content_type,
96+
"response": {"contentType": response_content_type},
97+
}
98+
)
6899

69-
Returns:
70-
[dict]: Form description
71-
"""
72-
return build_forms_for_view(rules, view, op=["invokeaction"])
100+
# HTTP writeproperty requires PUT method
101+
if hasattr(view, "put"):
102+
for url in prop_urls:
103+
forms.append(
104+
{
105+
"op": ["writeproperty"],
106+
"htv:methodName": "PUT",
107+
"href": url,
108+
"contentType": content_type,
109+
"response": {"contentType": response_content_type},
110+
}
111+
)
112+
# HTTP writeproperty may use POST method
113+
elif hasattr(view, "post"):
114+
for url in prop_urls:
115+
forms.append(
116+
{
117+
"op": ["writeproperty"],
118+
"htv:methodName": "POST",
119+
"href": url,
120+
"contentType": content_type,
121+
"response": {"contentType": response_content_type},
122+
}
123+
)
124+
125+
return forms
73126

74127

75128
class ThingDescription:

0 commit comments

Comments
 (0)