<p dir="auto">Since the verify parameter is designed with the certificate stored on the filesystem, I have had to do some workarounds in my application, since I am expecting certificates to be passed in using environment variables. While experimenting with these workarounds, I noticed some strange behaviors.</p>
<p dir="auto">Main Issue:</p>
<ul dir="auto">
<li>The docs claim that path/path-like objects are the intended use case, however, you are able to pass some things in that aren't path-like, and it is able to work.</li>
<li>You should definitely be able to just pass in a certificate as a variable, why is this not supported?</li>
</ul>
<p dir="auto">Please read the <em>Reproduction Steps</em> below, that is best way to understand the issue.</p>
<h2 dir="auto">Expected Result</h2>
<p dir="auto">When using the verify= parameter, I expect to be able to pass in these types of objects:</p>
<ul dir="auto">
<li>string of path</li>
<li>os.PathLike</li>
</ul>
<p dir="auto">Current Error Message, when passing in a wrong Type:<br>
TypeError: stat: path should be string, bytes, os.PathLike or integer, not _io.StringIO</p>
<h2 dir="auto">Actual Result</h2>
<p dir="auto">Things passed in that could work:</p>
<ul dir="auto">
<li>certificate in string form, however only when using .read() function</li>
<li>path or pathlike of certificate</li>
</ul>
<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
from io import StringIO
import os
import tempfile

## Get certificate stored in env variable
tls = os.getenv(&quot;TLS&quot;)

## Do some conversions of the certificate
# StringIO Form
f = StringIO(codecs.decode(tls, encoding=&quot;hex&quot;).decode())

# String Form
y = f.read()

# Tempfile Form
a = bytes.fromhex(tls)
fp = tempfile.NamedTemporaryFile()
fn = fp.name
fp.write(a)
fp.seek(0)
cert_path = fn


## Use the certificate in various ways:
requests.get(&quot;https://192.168.1.12:8080/v1/getinfo&quot;, headers=headers, verify=cert_path).json()
# Successful, most canonical way to do it

requests.get(&quot;https://192.168.1.12:8080/v1/getinfo&quot;, headers=headers, verify=f.read()).json()
# Successful, throws WARNING: InsecureRequestWarning: Unverified HTTPS request is being made to host '192.168.1.12'. # Adding certificate verification is strongly advised.
# Since it was successful, it seems the warning isn't valid, since an unverified HTTPS requests was not sent.

requests.get(&quot;https://192.168.1.12:8080/v1/getinfo&quot;, headers=headers, verify=y).json()
# Failure: OSError: Could not find a suitable TLS CA certificate bundle, invalid path: ..."><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">requests</span>
<span class="pl-k">from</span> <span class="pl-s1">io</span> <span class="pl-k">import</span> <span class="pl-v">StringIO</span>
<span class="pl-k">import</span> <span class="pl-s1">os</span>
<span class="pl-k">import</span> <span class="pl-s1">tempfile</span>

<span class="pl-c">## Get certificate stored in env variable</span>
<span class="pl-s1">tls</span> <span class="pl-c1">=</span> <span class="pl-s1">os</span>.<span class="pl-en">getenv</span>(<span class="pl-s">"TLS"</span>)

<span class="pl-c">## Do some conversions of the certificate</span>
<span class="pl-c"># StringIO Form</span>
<span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-v">StringIO</span>(<span class="pl-s1">codecs</span>.<span class="pl-en">decode</span>(<span class="pl-s1">tls</span>, <span class="pl-s1">encoding</span><span class="pl-c1">=</span><span class="pl-s">"hex"</span>).<span class="pl-en">decode</span>())

<span class="pl-c"># String Form</span>
<span class="pl-s1">y</span> <span class="pl-c1">=</span> <span class="pl-s1">f</span>.<span class="pl-en">read</span>()

<span class="pl-c"># Tempfile Form</span>
<span class="pl-s1">a</span> <span class="pl-c1">=</span> <span class="pl-s1">bytes</span>.<span class="pl-en">fromhex</span>(<span class="pl-s1">tls</span>)
<span class="pl-s1">fp</span> <span class="pl-c1">=</span> <span class="pl-s1">tempfile</span>.<span class="pl-v">NamedTemporaryFile</span>()
<span class="pl-s1">fn</span> <span class="pl-c1">=</span> <span class="pl-s1">fp</span>.<span class="pl-s1">name</span>
<span class="pl-s1">fp</span>.<span class="pl-en">write</span>(<span class="pl-s1">a</span>)
<span class="pl-s1">fp</span>.<span class="pl-en">seek</span>(<span class="pl-c1">0</span>)
<span class="pl-s1">cert_path</span> <span class="pl-c1">=</span> <span class="pl-s1">fn</span>


<span class="pl-c">## Use the certificate in various ways:</span>
<span class="pl-s1">requests</span>.<span class="pl-en">get</span>(<span class="pl-s">"https://192.168.1.12:8080/v1/getinfo"</span>, <span class="pl-s1">headers</span><span class="pl-c1">=</span><span class="pl-s1">headers</span>, <span class="pl-s1">verify</span><span class="pl-c1">=</span><span class="pl-s1">cert_path</span>).<span class="pl-en">json</span>()
<span class="pl-c"># Successful, most canonical way to do it</span>

<span class="pl-s1">requests</span>.<span class="pl-en">get</span>(<span class="pl-s">"https://192.168.1.12:8080/v1/getinfo"</span>, <span class="pl-s1">headers</span><span class="pl-c1">=</span><span class="pl-s1">headers</span>, <span class="pl-s1">verify</span><span class="pl-c1">=</span><span class="pl-s1">f</span>.<span class="pl-en">read</span>()).<span class="pl-en">json</span>()
<span class="pl-c"># Successful, throws WARNING: InsecureRequestWarning: Unverified HTTPS request is being made to host '192.168.1.12'. # Adding certificate verification is strongly advised.</span>
<span class="pl-c"># Since it was successful, it seems the warning isn't valid, since an unverified HTTPS requests was not sent.</span>

<span class="pl-s1">requests</span>.<span class="pl-en">get</span>(<span class="pl-s">"https://192.168.1.12:8080/v1/getinfo"</span>, <span class="pl-s1">headers</span><span class="pl-c1">=</span><span class="pl-s1">headers</span>, <span class="pl-s1">verify</span><span class="pl-c1">=</span><span class="pl-s1">y</span>).<span class="pl-en">json</span>()
<span class="pl-c"># Failure: OSError: Could not find a suitable TLS CA certificate bundle, invalid path: ...</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;3.2&quot;
  },
  &quot;idna&quot;: {
    &quot;version&quot;: &quot;2.10&quot;
  },
  &quot;implementation&quot;: {
    &quot;name&quot;: &quot;CPython&quot;,
    &quot;version&quot;: &quot;3.8.5&quot;
  },
  &quot;platform&quot;: {
    &quot;release&quot;: &quot;5.8.0-7642-generic&quot;,
    &quot;system&quot;: &quot;Linux&quot;
  },
  &quot;pyOpenSSL&quot;: {
    &quot;openssl_version&quot;: &quot;1010108f&quot;,
    &quot;version&quot;: &quot;20.0.1&quot;
  },
  &quot;requests&quot;: {
    &quot;version&quot;: &quot;2.25.0&quot;
  },
  &quot;system_ssl&quot;: {
    &quot;version&quot;: &quot;1010106f&quot;
  },
  &quot;urllib3&quot;: {
    &quot;version&quot;: &quot;1.25.10&quot;
  },
  &quot;using_pyopenssl&quot;: true
}"><pre class="notranslate"><code class="notranslate">{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": "3.2"
  },
  "idna": {
    "version": "2.10"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.8.5"
  },
  "platform": {
    "release": "5.8.0-7642-generic",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "1010108f",
    "version": "20.0.1"
  },
  "requests": {
    "version": "2.25.0"
  },
  "system_ssl": {
    "version": "1010106f"
  },
  "urllib3": {
    "version": "1.25.10"
  },
  "using_pyopenssl": true
}
</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">Since requests can be attached with an auth method, and there is oauth files in the package, so we can pass auth method to requests in order to archive auto auth function.<br>
However, the code of oauth is conflicting with current trunk code.<br>
Let's see<br>
<a href="https://github.com/kennethreitz/requests/blob/develop/requests/models.py#L535">https://github.com/kennethreitz/requests/blob/develop/requests/models.py#L535</a><br>
So if i pass in a dict object as post data, content-type will be set automatically.<br>
Then see here<br>
<a href="https://github.com/kennethreitz/requests/blob/develop/requests/auth.py#L81">https://github.com/kennethreitz/requests/blob/develop/requests/auth.py#L81</a><br>
If content-type is set, oauth won't work! It expects signing will be executed by manual operation!<br>
Let's summarize all things:<br>
Content-Type is set for the existence of non-plain dict object, oauth rejects to work for the existence of content-type.<br>
WTF!<br>
Either cancel automatically adding content-type or always sign the request without thinking about content-type will finally solve the problem.<br>
Plz fix it.</p>