<p dir="auto">When using allow_redirect=True, user can set a callback on each 'response' (via the hook parameter) but not on 'request'.<br>
This is a problem when using the redirect capability because user loose the ability to interact with the request before it is being sent.<br>
This would allow a user to do things such as: Log all incoming requests (and all redirect) in real time / modify the header between redirected calls / modify argument or payload between calls / or change http method between redirects / ...</p>
<p dir="auto">Locally I can fix this by changing:</p>
<ul dir="auto">
<li>hook.py:
<ul dir="auto">
<li>Adding a 'request' to the HOOK list at line 14:<br>
HOOKS = ['response', 'request'])</li>
</ul>
</li>
<li>Session.py
<ul dir="auto">
<li>move line 637 to 633:<br>
hook = request.hooks</li>
<li>add a callback line 634:<br>
dispatch_hook('request', hooks, request, **kwargs)</li>
</ul>
</li>
</ul>
<p dir="auto">But I don't want to have a frankenversion of "requests.py" on my system. And I'm not familiar enough to have a good "proposed change" from GitHub (without potentially causing unintended side effects).</p>
<h2 dir="auto">Expected Result</h2>
<p dir="auto">The 'response' hook should be triggered just before making the adapter.send (initially and more importantly for all subsequent redirects).<br>
The default_hook (hook.py) should have an entry for 'request' along with 'response'</p>
<h2 dir="auto">Actual Result</h2>
<p dir="auto">When redirect happen, mulitple 'response' callback are triggered but no 'request' callback.</p>
<p dir="auto">What happened instead.</p>
<h2 dir="auto">Reproduction Steps</h2>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import requests

LOG = logging.getLogger(__name__)    

# ( in real scenario, there would be something more interesting than logging here - but good enough for repro steps).
def _log_request(self, prepared_request):
    LOG.info(&quot;HTTP Request&quot;)           
    LOG.info(&quot;-&gt; %s %s&quot; % (prepared_request.method.upper(), prepared_request.url))           
    if prepared_request.body:
        LOG.info(&quot;-&gt; (Payload) %s&quot; % prepared_request.body)
    for key,value in prepared_request.headers.items():
        LOG.info(&quot;-&gt; %s: %s&quot; % (key,value))

def _log_response(self, resp):
    LOG.info(&quot;HTTP Response for '%s'&quot; % resp.url)
    LOG.info(&quot;&lt;- Status Code = %s&quot; % resp.status_code)
    for (key,value) in resp.headers.items():
        LOG.info(&quot;&lt;- %s: %s&quot; % (key,value) )

session = requests.Session()
session.get(url, headers=_headers, hooks={&quot;response&quot;:_log_response, &quot;request&quot;:_log_request}, allow_redirects=True)"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">requests</span>

<span class="pl-v">LOG</span> <span class="pl-c1">=</span> <span class="pl-s1">logging</span>.<span class="pl-en">getLogger</span>(<span class="pl-s1">__name__</span>)    

<span class="pl-c"># ( in real scenario, there would be something more interesting than logging here - but good enough for repro steps).</span>
<span class="pl-k">def</span> <span class="pl-en">_log_request</span>(<span class="pl-s1">self</span>, <span class="pl-s1">prepared_request</span>):
    <span class="pl-v">LOG</span>.<span class="pl-en">info</span>(<span class="pl-s">"HTTP Request"</span>)           
    <span class="pl-v">LOG</span>.<span class="pl-en">info</span>(<span class="pl-s">"-&gt; %s %s"</span> <span class="pl-c1">%</span> (<span class="pl-s1">prepared_request</span>.<span class="pl-s1">method</span>.<span class="pl-en">upper</span>(), <span class="pl-s1">prepared_request</span>.<span class="pl-s1">url</span>))           
    <span class="pl-k">if</span> <span class="pl-s1">prepared_request</span>.<span class="pl-s1">body</span>:
        <span class="pl-v">LOG</span>.<span class="pl-en">info</span>(<span class="pl-s">"-&gt; (Payload) %s"</span> <span class="pl-c1">%</span> <span class="pl-s1">prepared_request</span>.<span class="pl-s1">body</span>)
    <span class="pl-k">for</span> <span class="pl-s1">key</span>,<span class="pl-s1">value</span> <span class="pl-c1">in</span> <span class="pl-s1">prepared_request</span>.<span class="pl-s1">headers</span>.<span class="pl-en">items</span>():
        <span class="pl-v">LOG</span>.<span class="pl-en">info</span>(<span class="pl-s">"-&gt; %s: %s"</span> <span class="pl-c1">%</span> (<span class="pl-s1">key</span>,<span class="pl-s1">value</span>))

<span class="pl-k">def</span> <span class="pl-en">_log_response</span>(<span class="pl-s1">self</span>, <span class="pl-s1">resp</span>):
    <span class="pl-v">LOG</span>.<span class="pl-en">info</span>(<span class="pl-s">"HTTP Response for '%s'"</span> <span class="pl-c1">%</span> <span class="pl-s1">resp</span>.<span class="pl-s1">url</span>)
    <span class="pl-v">LOG</span>.<span class="pl-en">info</span>(<span class="pl-s">"&lt;- Status Code = %s"</span> <span class="pl-c1">%</span> <span class="pl-s1">resp</span>.<span class="pl-s1">status_code</span>)
    <span class="pl-k">for</span> (<span class="pl-s1">key</span>,<span class="pl-s1">value</span>) <span class="pl-c1">in</span> <span class="pl-s1">resp</span>.<span class="pl-s1">headers</span>.<span class="pl-en">items</span>():
        <span class="pl-v">LOG</span>.<span class="pl-en">info</span>(<span class="pl-s">"&lt;- %s: %s"</span> <span class="pl-c1">%</span> (<span class="pl-s1">key</span>,<span class="pl-s1">value</span>) )

<span class="pl-s1">session</span> <span class="pl-c1">=</span> <span class="pl-s1">requests</span>.<span class="pl-v">Session</span>()
<span class="pl-s1">session</span>.<span class="pl-en">get</span>(<span class="pl-s1">url</span>, <span class="pl-s1">headers</span><span class="pl-c1">=</span><span class="pl-s1">_headers</span>, <span class="pl-s1">hooks</span><span class="pl-c1">=</span>{<span class="pl-s">"response"</span>:<span class="pl-s1">_log_response</span>, <span class="pl-s">"request"</span>:<span class="pl-s1">_log_request</span>}, <span class="pl-s1">allow_redirects</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)</pre></div>
<h2 dir="auto">System Information</h2>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ python -m requests.help"><pre class="notranslate"><code class="notranslate">$ python -m requests.help
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{
  &quot;chardet&quot;: {
    &quot;version&quot;: &quot;3.0.4&quot;
  },
  &quot;cryptography&quot;: {
    &quot;version&quot;: &quot;&quot;
  },
  &quot;idna&quot;: {
    &quot;version&quot;: &quot;2.7&quot;
  },
  &quot;implementation&quot;: {
    &quot;name&quot;: &quot;CPython&quot;,
    &quot;version&quot;: &quot;3.6.5&quot;
  },
  &quot;platform&quot;: {
    &quot;release&quot;: &quot;17.7.0&quot;,
    &quot;system&quot;: &quot;Darwin&quot;
  },
  &quot;pyOpenSSL&quot;: {
    &quot;openssl_version&quot;: &quot;&quot;,
    &quot;version&quot;: null
  },
  &quot;requests&quot;: {
    &quot;version&quot;: &quot;2.19.1&quot;
  },
  &quot;system_ssl&quot;: {
    &quot;version&quot;: &quot;100020ef&quot;
  },
  &quot;urllib3&quot;: {
    &quot;version&quot;: &quot;1.23&quot;
  },
  &quot;using_pyopenssl&quot;: false
}

"><pre class="notranslate"><code class="notranslate">{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.5"
  },
  "platform": {
    "release": "17.7.0",
    "system": "Darwin"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.19.1"
  },
  "system_ssl": {
    "version": "100020ef"
  },
  "urllib3": {
    "version": "1.23"
  },
  "using_pyopenssl": false
}


</code></pre></div>
<p dir="auto">This command is only available on Requests v2.16.4 and greater. Otherwise,<br>
please provide some basic information about your system (Python version,<br>
operating system, &amp;c).</p>
<p dir="auto">There was a scenario where I need to intercept the request and was searching for if there is some way can that be done, then I found the event hook but only <code class="notranslate">response</code> event hook is supported.<br>
I hope adding <code class="notranslate">request</code> hook can be useful, if yes I would like to implement that.</p>
<p dir="auto">Any pointers or suggestion appreciated.</p>
<p dir="auto">Thanks</p>