2 from datetime import timedelta
10 op_provision = ":8181/restconf/operations/onem2m:onem2m-cse-provisioning"
11 op_tree = ":8181/restconf/operational/onem2m:onem2m-resource-tree"
12 op_cleanup = ":8181/restconf/operations/onem2m:onem2m-cleanup-store"
30 application_payload = """
34 {"aei":"jb", "api":"jb", "apn":"jb2", "or":"http://hey/you" %s}
39 _container_payload = """
47 "or": "http://hey/you"
54 container_payload = """
60 "or": "http://hey/you"
67 contentInstance_payload = """
72 "or": "http://hey/you"
80 def which_payload(restype):
81 """Return a template payload for the known datatypes."""
82 if restype == application:
83 return application_payload
84 elif restype == container:
85 return container_payload
86 elif restype == contentInstance:
87 return contentInstance_payload
92 def find_key(response, key):
95 return val["any"][0][key]
101 """Return the resource name in the response."""
102 return find_key(response, "rn")
106 """Return the resource id in the response."""
107 return find_key(response, "ri")
110 def parent(response):
111 """Return the parent resource id in the response."""
112 return find_key(response, "pi")
115 def content(response):
116 """Return the content the response."""
117 return find_key(response, "con")
120 def restype(response):
121 """Return the resource type the response."""
122 return find_key(response, "rty")
125 def status(response):
126 """Return the protocol status code in the response."""
128 return response.status_code
133 def headers(response):
134 """Return the protocol headers in the response."""
136 return response.headers
142 """Return the error string in the response."""
144 return response.json()["error"]
157 """Convert a dictionary into a string for a protocol payload."""
168 if i != "con" and n.isdigit():
169 content = content + "'%s':%d%s" % (i, int(n), sep)
171 content = content + "'%s':'%s'%s" % (i, n, sep)
181 auth=("admin", "admin"),
184 """Connect to a IoTDM server."""
185 self.s = requests.Session()
187 self.s.headers.update({"content-type": "application/json"})
188 self.timeout = (5, 5)
189 self.payload = cse_payload % (base)
191 # Admittedly these are "magic values" but are required
192 # and until a proper defaulting initializer is in place
194 "content-type": "application/json",
195 "X-M2M-Origin": "//localhost:10000",
199 self.server = "http://" + server
201 self.url = self.server + op_provision
202 self.r = self.s.post(self.url, data=self.payload, timeout=self.timeout)
204 def create(self, parent, restype, name=None, attr=None):
205 """Create resource."""
208 payload = which_payload(restype)
209 payload = payload % (attr2str(attr))
211 self.headers["X-M2M-NM"] = None
213 self.headers["X-M2M-NM"] = name
214 parent = normalize(parent)
215 self.url = self.server + ":8282/%s?ty=%s&rcn=1" % (parent, restype)
216 self.r = self.s.post(
217 self.url, payload, timeout=self.timeout, headers=self.headers
221 def retrieve(self, id):
222 """Retrieve resource."""
226 self.url = self.server + ":8282/%s?rcn=5&drt=2" % (id)
227 self.headers["X-M2M-NM"] = None
228 self.r = self.s.get(self.url, timeout=self.timeout, headers=self.headers)
231 def update(self, id, attr=None):
232 """Update resource attr"""
238 def delete(self, id):
239 """Delete the resource with the provided ID."""
243 self.url = self.server + ":8282/%s" % (id)
244 self.headers["X-M2M-NM"] = None
245 self.r = self.s.delete(self.url, timeout=self.timeout, headers=self.headers)
249 """Get the resource tree."""
250 self.url = self.server + op_tree
251 self.r = self.s.get(self.url)
256 self.url = self.server + op_cleanup
257 self.r = self.s.post(self.url)