There is my code I'm trying to do:
import json
import requests
class Request(object):
def __init__(self, method, path):
self.method = method
## Q1
self.url = ''.join([***MyClass.host***, path])
self.h = {
"Content-Type": "application/json;charset=UTF-8"
}
def __call__(self, f):
def wrapper(*args, **kwargs):
# Q2
getattr(requests, self.method)(url = self.url, headers = h***, data = json.dumps(body)***)
return wrapper
class MyClass(object):
def __init__(self, host):
self.host = host
@Request(method = "post", path = "/add_mission")
def AddMission(self, mission):
body = {
"mission_id": mission
}
@Request(method = "get", path = "/system_info")
def GetInfo(self):
print("I want get info")
There are some questions hope someone can solve my problems:
1. How can my decorator "Request" get the variable "host" from "MyClass"? (In comment ## Q1)
2. How can I pass the function's variable "body" to decorator, is it possible? (In comment ## Q2)
Because I need to access different url(host+path) with [post, get, delete]. I'm not sure isn't decorator match on this case? Or maybe there are better ways to deal with this case?
The host is available once you call the decorated function, via the invoking object's host
attribute, so wait until you actually call the method to build the URL. You'll want to call the underlying function to get back a value, if any, to use as the payload.
import json
import requests
class Request(object):
def __init__(self, method, path):
self.method = method.upper()
self.h = {
"Content-Type": "application/json;charset=UTF-8"
}
self.path = path
def __call__(self, f):
def wrapper(obj, *args, **kwargs):
payload = f(*args, **kwargs)
args = {
'method': self.method,
'url': 'http://{}/{}'.format(obj.host, self.path),
'headers': self.h
}
if payload is not None:
args['json'] = payload
return requests.request(**args)
return wrapper
class MyClass(object):
def __init__(self, host):
self.host = host
@Request(method="post", path="/add_mission")
def AddMission(self, mission):
return {"mission_id": mission}
@Request(method="get", path="/system_info")
def GetInfo(self):
print("I want get info")
Then you can write, for example,
api = MyClass("www.example.com")
add_response = api.AddMission("mars")
info_response = api.GetInfo()
Each decorated function returns the Response
object produced by the call to requests.request
.
You might consider subclasses of Request
for each method:
class GetRequest(Request):
def __init__(self, path):
super().__init__("GET", path)
class PostRequest(Request):
def __init__(self, path):
super().__init__("POST", path)
# etc