title: Python requests - quickly know if response is json parsable
body: <p>I wrote a certain API wrapper using Python's <code>requests</code> library.</p>
  
  <p>When it gets a response using <code>requests.get</code>, it attempts to parse as json and takes the raw content if it doesn't work:</p>
  
  <pre><code>resp = requests.get(url, ...)  
  
  try:
      resp_content = resp.json()
  except ValueError:
      resp_content = resp.content
  
  return resp_content
  </code></pre>
  
  <p>This is correct for my purposes. The problem is how long it takes when the downloaded response is an image file, for example, if it is large, then it takes an extremely long time between entering the <code>try</code>, and failing the json parse and entering the <code>except</code>.</p>
  
  <p>(I don't know if it takes super long for the <code>.json()</code> to error at all, or if once it errors it then takes a while to get into the <code>except</code>.)</p>
  
  <p>Is there a way to see if <code>resp</code> is json-parsable without attempting to parse it with <code>.json()</code>? Something like <code>resp.is_json</code>, so I can instantly know which branch to take (<code>resp.json()</code> or <code>resp.content</code>), instead of waiting 30 seconds (large files can take minutes).</p>
  
  <p>EDIT:</p>
  
  <p>As noted, this slowness is not typical for <code>requests</code> json parsing. It may have to do with the nature of the data I am receiving (it is from Salesforce REST API, retrieving Attachment object's 'Body' field).</p>
  
  <p>Even though it's a workaround, I will put my solution here in case the strategy helps anyone else. I realized where I'm making the call, I usually know if I expect the response to be binary data, so I can pass a keyword argument to my wrapper function that tells it to skip the json parsing attempt.</p>
  
  <pre><code>def SalesforceWrapper(..., attempt_json=True):
  
      resp = requests.get(url, ...)  
  
      try:
          if attempt_json:
              resp_content = resp.json()
          else:
              resp_content = resp.content
      except ValueError:
          resp_content = resp.content
  
      return resp_content
  </code></pre>
  
  <p>and then I pass <code>attempt_json=False</code> when I expect the response to be a file's data, not a lil JSON response.</p>