Search code examples
pythonpython-decoratorsmonkeypatching

Python: Monkeypatching a method of an object


I'm hitting an API in python through requests' Session class. I'm making GET & POST method call using requests.Session().

On every call(GET/POST) failure, I want to notify another process. I can do this by creating a utility method as follows:

s = request.Session()
def post():
    try:
        s.post(URL,data,headers)
    except:
        notify_another_process()

And call this method instead of requests.Session().post directly.

But, I want to monkeypatch this code to requests.Session().post and want the additional functionality of notifying the other process in the requests.Session().post method call itself. How can I achieve this?

EDIT 1 :

requests.Session()'s post method has the following signature:

def post(self, url, data=None, json=None, **kwargs):
    return self.request('POST', url, data=data, json=json, **kwargs)

If I somehow try to make my a custom post like the following:

def post_new(self, url, data=None, json=None, **kwargs):
    try:
        s.post(url,data, json,kwargs)
    except:
        notify_another_process()

and do a patch as follows:

requests.post = post_new

This isn't really a good monkeypatching because I'm not using self but session's object inside session.post.


Solution

  • This is the answer which worked for me. It is inspired by the answers mentioned by Siddharth & lafferc both. This is on top of what both of them mentioned.

    >>> import requests
    >>> def post(self, url, data=None, json=None, **kwargs):
    ...     try:
    ...         raise Exception()
    ...     except:
    ...         print "notifying another process"
    ... 
    >>> setattr(requests.Session, 'post_old', requests.Session.post)
    >>> setattr(requests.Session, 'post', post)
    >>> s = requests.Session()
    >>> s.post("url")
    notifying another process