a subclass of models.Response can now be passed to get, post etc

`models.Response` can't easily be subclassed (I'm making the assumption that there isn't a way that I don't know about)

I'd like to be able to pass a subclass of `models.Response` to `get`, `post` etc. I know there is a `response` hook however I don't want to do something like `response.__class__ = MyResponse` or add custom methods to the `Response` instance one by one. Being able to subclass would be much cleaner.


What is the use case for passing in a subclass of Response to get, post etc.. ? 


I saw the comment somewhere that it had been discussed and decided that requests is a http library not a html library (a good decision in my opinion), however there will be many people (myself included) that will use requests.get on a html page and parse resp.content with lxml or similar then do what they need to do. 

By adding the ability to subclass `Response` you provide users the freedom add their own functionality (html parsing etc) whilst maintaining requests' core values (eg http only). 

See this example of what I want to be able to do (not sure the `__getattr__` method would work but it gives the idea).  

```
import requests
import lxml

class MyResponse(requests.models.Response):
    def xpath(self, expression):
        results = []
        for result in self._etree.xpath(expression):
            if expression.endswith('href') or expression.endswith('src') and not result.startswith('http'):
                result = urljoin(self.url, result)
            results.append(result)
        return results

    def get_etree(self):
        return self._etree

    def __getattr__(self, name):
        """
        Read and returns the full stream when accessing to :attr: `content`
        And sets up :attr: `_etree` if accessed.
        """
        if name == '_etree':
            if not self.__dict__.get('_etree'):
                self._etree = etree.HTML(self.content)
            return self._etree

        else:
            super(requests.models.Response, self).__getattr__(name)

tree = requests.get('http://www.somesite.com', response_class=MyResponse).get_etree()
urls = requests.get('http://www.anothersite.com', response_class=MyResponse).xpath('//a/@href')
>>> ['http://foo.com','http://bar.com/baz.html]
```

The alternatives to this involve nasty hacks within the `response` hook.


Wouldn't a less leaky abstraction be to create your own request helper class (wrapper), that abstracts both the request and the response away, instead of attempting to modify the existing class hierarchy?


Not sure I understand, can you elaborate?


Maybe something like this. Using a class in this example, as you could pass in the xpath you are looking for on construction possibly. A simpler case would just be a method wrapper for 'get' or something like that.

``` python
import functools
import requests

class WrapperClient(object):
    def __init__(self, *args, **kwds):
        ## some init here...

    def __getattr__(self, method_name):
        mlower = method_name.lower()
        if mlower in requests.api.__all__:
            # partial application
            return functools.partial(self._request, mlower)
        else:
            raise AttributeError(method_name)

    def _request(self, http_method, url, *args, **kwds):
        resp = getattr(requests, http_method)(url, *args, **kwds)
        ## do something with resp. xpath, etc
        return resp # or whatever you want
```

edit: fixed the code a bit. sorry! it was late here.. :/


:+1: @cactus.


Was going to say that using wrappers makes it difficult to use sessions, additionallly the beautiful api is lost unless you copy lots of code from api.


Sessions don't have to be used as context managers.

You can simply toss around the session:

``` python
s = requests.session()

def get(*args, **kwargs):
    r = s.get(*args, **kwargs)
    # do something to r
    return r
```


Another suggest: you can just pass in an `post_request` hook to the session that returns your new `Response` object, bootstrapped from the one Requests returns. Very simple and elegant.


Bootstrapping from the existing `Response` was my very first thought but it felt messy.

I've made a decorator that adds a `response` hook which replaces `Response` with a wrapped version, decorator for individual requests, hook function for sessions (with `with`).

I take your (and cactus') points however it would be more user friendly to be able to simply subclass Response. You can provide a `CookieJar` or `auth` instance so why not `Response` (or class due to the implementation)... food for thought.

Anyway, thank you both for your suggestions.


I certainly see where you are coming from @j0hnsmith.
My example was indeed simplistic (geared towards that one simple example you had presented).
Glad you found a work around that is tenable given your requirements and use case. 

I think the argument against passing in a response object is that all the other method parameters modify the request and request behavior, and not the response. Providing a custom response object could have other repercussions inside the request handling, and might require more runtime checking to make sure expected methods are present. That could be a pain.

I think using a decorator to add a response hook is a pretty clean way to go. nice.


I use a response hook for xpath queries see https://gist.github.com/2714629


So what's with response_class= ?...


@nfx this pull request wasn't excepted. There never was such a feature.