psf / requests

A simple, yet elegant, HTTP library.
https://requests.readthedocs.io/en/latest/
Apache License 2.0
52.19k stars 9.33k forks source link

chunked put using a generator function... #6823

Closed steve-osfda closed 1 week ago

steve-osfda commented 1 week ago

I made a generator function that returns str chunks; I passed it to data [...data=my_func()...], and it eventually comes back with the error "memoryview: a bytes-like object is required, not 'str'" (debug statements indicate this is happening on the first yield...)

Documentation indicates this is the way to do it: https://docs.python-requests.org/en/latest/user/advanced/#chunk-encoded-requests

Expected Result

No error!

Actual Result

The error "memoryview: a bytes-like object is required, not 'str'".

Reproduction Steps

import requests

def test():
    json_preamble='{"field": "value",'
    def put()->str:
        yield json_preamble

        return '"field2": "value2"}' # final chunk...

    response=requests.put(some_url, data=put(), headers=some_headers)

test ()

System Information

$ python -m requests.help
{
  "chardet": {
    "version": "5.1.0"
  },
  "charset_normalizer": {
    "version": "3.0.1"
  },
  "cryptography": {
    "version": "38.0.4"
  },
  "idna": {
    "version": "3.3"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.11.2"
  },
  "platform": {
    "release": "6.1.0-26-amd64",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "30000080",
    "version": "23.0.0"
  },
  "requests": {
    "version": "2.28.1"
  },
  "system_ssl": {
    "version": "300000e0"
  },
  "urllib3": {
    "version": "1.26.12"
  },
  "using_charset_normalizer": false,
  "using_pyopenssl": true
}
steve-osfda commented 1 week ago

PS A put using a file descriptor as the data argument (opened 'rb' to a .json file...) works...

steve-osfda commented 1 week ago

PPS I also tried returning byte strings, even though the documentation example does not do that, and it also fails, with a 400, bad request...

nateprewitt commented 1 week ago

Hi @steve-osfda, this issue was patched in 2.29.0 early last year. If you update to a more recent version, you should no longer encounter this issue.

I would also suggest double checking your generator is actually producing what you're expecting. Your return will not be included in the generator, only the StopIteration exception raised at the end. You're only sending {"field": "value",' over the wire which is likely the cause of your 400.

steve-osfda commented 1 week ago

That was the ticket for the version that returned bytes! A generator needs an [implicit] return None

I will run with the bytes-encloded return for now (checking the requests version and act accordingly...) Debian bookworm stable right now uses 2.28.

Thank you so much for your speedy response!