title: Python urllib.request.Request parameter 'data' object type
body: <p>I try to use  <strong>urllib.request.Request</strong> (Python 3.6.7) to make an API call to a internal web services to get some json results. I need to send some data and headers to the server, so I use the <strong>urllib.request.Request</strong> class to do this. For the input of <strong>data</strong>, I try to find out what is the format it will accept. From the Python <a href="https://docs.python.org/3.6/library/urllib.request.html#module-urllib.request" rel="nofollow noreferrer">docs</a>, it says:</p>
  
  <blockquote>
    <p>The supported object types include bytes, file-like objects, and
    <strong>iterables</strong>.</p>
  </blockquote>
  
  <p>So I use a <em>dictionary</em> data type for this parameter <strong>data</strong>. Here is my code:</p>
  
  <pre><code>import urllib
  
  my_url = "https://httpbin.org/post"
  my_headers = { "Content-Type" : "application/x-www-form-urlencoded" }
  my_data = {
          "client_id" : "ppp",
          "client_secret" : "000",
          "grant_type" : "client_credentials" }
  
  req = urllib.request.Request(url=my_url, data=my_data, headers=my_headers)
  response = urllib.request.urlopen(req)
  html = response.read()
  print(html)
  </code></pre>
  
  <p>I then get error like this:</p>
  
  <pre><code>Traceback (most recent call last):
    File "./callapi.py", line 23, in &lt;module&gt;
      response = urllib.request.urlopen(req)
    File "/usr/lib64/python3.6/urllib/request.py", line 223, in urlopen
      return opener.open(url, data, timeout)
    File "/usr/lib64/python3.6/urllib/request.py", line 526, in open
      response = self._open(req, data)
    File "/usr/lib64/python3.6/urllib/request.py", line 544, in _open
      '_open', req)
    File "/usr/lib64/python3.6/urllib/request.py", line 504, in _call_chain
      result = func(*args)
    File "/usr/lib64/python3.6/urllib/request.py", line 1361, in https_open
      context=self._context, check_hostname=self._check_hostname)
    File "/usr/lib64/python3.6/urllib/request.py", line 1318, in do_open
      encode_chunked=req.has_header('Transfer-encoding'))
    File "/usr/lib64/python3.6/http/client.py", line 1239, in request
      self._send_request(method, url, body, headers, encode_chunked)
    File "/usr/lib64/python3.6/http/client.py", line 1285, in _send_request
      self.endheaders(body, encode_chunked=encode_chunked)
    File "/usr/lib64/python3.6/http/client.py", line 1234, in endheaders
      self._send_output(message_body, encode_chunked=encode_chunked)
    File "/usr/lib64/python3.6/http/client.py", line 1064, in _send_output
      + b'\r\n'
  TypeError: can't concat str to bytes
  </code></pre>
  
  <p>I then follow the example in this <a href="https://docs.python.org/3.6/howto/urllib2.html#data" rel="nofollow noreferrer">docs</a> page, and change my code to:</p>
  
  <pre><code>import urllib
  
  my_url = "https://httpbin.org/post"
  my_headers = { "Content-Type" : "application/x-www-form-urlencoded" }
  my_data = {
          "client_id" : "ppp",
          "client_secret" : "000",
          "grant_type" : "client_credentials" }
  
  my_uedata = urllib.parse.urlencode(my_data)
  my_edata = my_uedata.encode('ascii')
  
  req = urllib.request.Request(url=my_url, data=my_edata,headers=my_headers)
  response = urllib.request.urlopen(req)
  html = response.read()
  print(html)
  </code></pre>
  
  <p>it then works.</p>
  
  <p>My question is, isn't it in the docs it says this class accept data type <strong>iterables</strong> ? why does my parameter in <em>dict</em> is wrong ? My final result that is working use <strong>str.encode()</strong> method which returns an <a href="https://docs.python.org/3.6/library/stdtypes.html?highlight=encode#string-methods" rel="nofollow noreferrer">byte object</a>, and it seems this class must take a byte object and not an iterables object. </p>
  
  <p>I am trying to use Python Standard Library docs as the main source of reference to code in Python, however I am having a hard time to use it, hope anybody can shed some light in helping me to understand more on how the library docs works, or if there is any other tutorial I need to go through before I can use it in a better way. Thanks. </p>