I’m writing an api and was wondering what’s the most pythonic way to do the following.
I’m writing a bunch of methods to do various web calls, the arguments mostly translate into post data keys and values.
The way I’ve been writing it so far is mostly like this;
def doSomething(self,param1,param2,param3):
payload={"param1":param1,
"param2":param2,
"param3":param3}
return self.request("do/something",payload)
This already has the draw back of having to repeat the parameter names which are subject to change, but this pattern isn’t too bad.
The following case is what got me trying to think of a better way. In this case there are 4 optional arguments for the call
def doSomethingElse(self,param1,param2=None,param3=None,param4=None,param5=None):
payload= {"param1":param1}
if param2:
payload["param2"]= param2
if param3:
payload["param3"]= param3
# ... etc ...
self.request("do/something/else",payload)
My first thought was to do this:
def doSomethingElse(self,param1,**params):
payload = {"param1":param1}
payload.update(params)
self.request("do/something/else",payload)
or even:
def doSomethingElse(self,**payload):
self.request("do/something/else",payload)
Although the second one is nice and simple, the method can be called without the non-default argument. But in both cases I lose the method signature when using the api and the user won’t know what the parameters are (I know I could write the expected signature in a docstring but I’d rather prevent misspelt keywords getting sent).
I’m thinking there must be a nice pythonic solution to do this, any ideas?
EDIT
I think a key point which I didn’t make clear enough is that the arguments are getting sent in post data in a call, and I want to make sure only those keys can get sent, like in the first example of doSomethingElse, you can’t send anything other than those 5 named parameters.
How about simply
which gives
which I think matches your criteria. The next step would be to use a decorator (probably with either wraps or the decorator module to preserve the signature) so that payload was computed and then passed, but I don’t know if
@payloadwould be all that much better thanpayload = get_payload(locals()). Note that usinglocals()this way, it needs to be done at the start.I second the feeling that this isn’t exactly the best way to prevent unwanted nuclear attacks, though.