Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File Uploading with Python 3.6.2 #377

Closed
jkeyes opened this issue Dec 1, 2017 · 7 comments
Closed

File Uploading with Python 3.6.2 #377

jkeyes opened this issue Dec 1, 2017 · 7 comments

Comments

@jkeyes
Copy link
Contributor

jkeyes commented Dec 1, 2017

Python Version: 3.6.2
Stripe: 1.75.1

The snippet from the Python docs for uploading a file is not working for me:

import stripe
stripe.api_key = 'sk_test_...'
with open("shoe.jpg", "r") as fp:
    stripe.FileUpload.create(
        file=fp,
        purpose="dispute_evidence",
    )

raises a UnicodeDecodeError:

Traceback (most recent call last):
  File "up.py", line 6, in <module>
    purpose="dispute_evidence",
  File "python3.6/site-packages/stripe/api_resources/file_upload.py", line 30, in create
    'post', url, params=params, headers=supplied_headers)
  File "python3.6/site-packages/stripe/api_requestor.py", line 151, in request
    method.lower(), url, params, headers)
  File "python3.6/site-packages/stripe/api_requestor.py", line 315, in request_raw
    generator.add_params(params or {})
  File "python3.6/site-packages/stripe/multipart_data_generator.py", line 36, in add_params
    self._write_file(value)
  File "python3.6/site-packages/stripe/multipart_data_generator.py", line 75, in _write_file
    file_contents = f.read(self.chunk_size)
  File "python3.6/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

Opening the file in rb mode also fails:

Traceback (most recent call last):
  File "up.py", line 6, in <module>
    purpose="dispute_evidence",
  File "python3.6/site-packages/stripe/api_resources/file_upload.py", line 30, in create
    'post', url, params=params, headers=supplied_headers)
  File "python3.6/site-packages/stripe/api_requestor.py", line 151, in request
    method.lower(), url, params, headers)
  File "python3.6/site-packages/stripe/api_requestor.py", line 335, in request_raw
    'Post details', post_data=post_data, api_version=self.api_version)
  File "python3.6/site-packages/stripe/util.py", line 87, in log_debug
    msg = logfmt(dict(message=message, **params))
  File "python3.6/site-packages/stripe/util.py", line 134, in logfmt
    return u' '.join([fmt(key, val) for key, val in sorted(props.items())])
  File "python3.6/site-packages/stripe/util.py", line 134, in <listcomp>
    return u' '.join([fmt(key, val) for key, val in sorted(props.items())])
  File "python3.6/site-packages/stripe/util.py", line 121, in fmt
    val = val.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 131: invalid start byte

The code is working under Python 2.7.13. I really feel like I must be overlooking something here, but I've tried various means with no success. Any ideas?

@jkeyes
Copy link
Contributor Author

jkeyes commented Dec 1, 2017

I've looked at #217 but there doesn't appear to be anything pertinent to this issue in there although the titles suggest otherwise.

@jkeyes
Copy link
Contributor Author

jkeyes commented Dec 1, 2017

If I comment out lines 119 and 120 in utils.py uploading works for Python 3.6.2:

119         # if six.PY3 and hasattr(val, 'decode'):
120         #    val = val.decode('utf-8')

@ob-stripe
Copy link
Contributor

Hey @jkeyes, thanks for the report!

If I understand correctly, there are two different issues here:

  • the sample requests on Stripe's site use "r" instead of "rb" to open image files. That should be easy enough to fix, I'll send a note to our docs team

  • even when using "rb", the library's logging feature trips on the file's contents. I'll investigate further and give an update here.

@ob-stripe
Copy link
Contributor

ob-stripe commented Dec 4, 2017

Okay, so it appears that we're logging the encoded post_data:

util.log_debug(
'Post details', post_data=post_data, api_version=self.api_version)

This works fine for regular x-www-form-urlencoded requests, but not so well for multipart-form requests.

I think we ought to log the params before encoding. It's what we do in the Ruby library: https://github.com/stripe/stripe-ruby/blob/d41a59fc82cd9989b16ebad9a4bcd9e39395466e/lib/stripe/stripe_client.rb#L443-L446. Files would simply be represented by their usual Python repr, e.g. <io.BufferedRandom name='/path/to/file.jpg'>.

cc @deontologician-stripe @brandur-stripe

@deontologician-stripe
Copy link
Contributor

Yeah, that makes a lot more sense. Nobody is going to want the encoded file contents in their logs anyway

@jkeyes
Copy link
Contributor Author

jkeyes commented Dec 4, 2017

PR #378 created. Without the change to api_requestor.py the test will fail. Hope that's sufficient.

@ob-stripe
Copy link
Contributor

Closing the issue as we released #378 in v1.75.3. Thanks again @jkeyes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants