Upload stream

Hello guys, I'm on python3 - requests  2.10.0.

Im trying to reproduce this:
http://docs.python-requests.org/en/master/user/advanced/#chunk-encoding

```
def gen():
    yield 'hi'
    yield 'there'

requests.post('http://some.url/chunked', data=gen())
```

But I get `File "C:\Users\Gabriel\AppData\Local\Programs\Python\Python35\lib\site-packages\requests\models.py", line 152, in _encode_files
    fdata = fp.read()
AttributeError: 'generator' object has no attribute 'read'`

Basically I wanna to be able to upload a file, and be able to trace the upload speed.


If I run the demo code in python3.5, I also get this Exception:

```
TypeError: a bytes-like object is required, not 'str'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "requests_test.py", line 10, in <module>
    r = requests.post('http://httpbin.org/post', data=gen())
  File "/Users/pegasus/Program/py3.5_test/lib/python3.5/site-packages/requests/api.py", line 111, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/Users/pegasus/Program/py3.5_test/lib/python3.5/site-packages/requests/api.py", line 57, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Users/pegasus/Program/py3.5_test/lib/python3.5/site-packages/requests/sessions.py", line 475, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/pegasus/Program/py3.5_test/lib/python3.5/site-packages/requests/sessions.py", line 585, in send
    r = adapter.send(request, **kwargs)
  File "/Users/pegasus/Program/py3.5_test/lib/python3.5/site-packages/requests/adapters.py", line 426, in send
    low_conn.send(i)
  File "/Users/pegasus/.pyenv/versions/3.5.0/lib/python3.5/http/client.py", line 889, in send
    self.sock.sendall(d)
TypeError: a bytes-like object is required, not 'str'.
```

is a bug?  Python3 should encode str to bytes.


@PegasusWang Python 3 should _not_ encode `str` to `bytes`. We cannot guess what encoding you might want, and guessing just leads to _really_ subtle bugs where you send a request you think is valid, get weird 400 errors, and then spend hours of your time and ours trying to work out why and it turns out it's because Requests defaulted to using UTF-8 and your server was expecting Latin-1. You, the user, are responsible for emitting bytes from your generator.

@maxibabyx Your sample code simply cannot be right, I'm afraid: or at least, it cannot be triggering the error you've provided. The branch of code you're in can only be entered in the following situation:
1. The value of your `data` argument does not provide the `__iter__` property, or it _does_ but is either a string, list, tuple, or dict from the perspective of `isinstance`.
2. The `files` keyword argument was also passed.

Your sample code does neither of these things, meaning that when I test it on my machine I do not encounter the bug you have encountered.

Can you confirm for me please that your sample code actually does reproduce your bug, ideally by providing a URL that is publicly reachable for me to test against myself?


You're rigth.
http://image.prntscr.com/image/8f573b147ab14755918cc0f5a3b3ba02.png

I get the error when I use the files keyword.
How can I get around ?


We do not support using a generator with the `files` keyword argument. This is in part because there is no value in it: the `files` keyword argument requires reading _all_ the data in to format it appropriately. 

Are you sure you need to send multipart/form-encoded data here? If you really do, you'll have to change it to `b''.join(gen())`.


I want to be able to upload in chunks, so my script doesn't get blocked until upload has finished.


If you want to do that then you can't use what Requests does by default. You'll need to use the [streaming multipart data encoder](https://toolbelt.readthedocs.io/en/latest/uploading-data.html#streaming-multipart-data-encoder) from the Requests toolbelt.