-
Notifications
You must be signed in to change notification settings - Fork 3k
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
SDK: fix string field serialization for multipart/form-data requests #5479
Conversation
Django REST Framework ignores the Content-Type on request body parts, so it doesn't know that they are JSON-encoded. Instead, it just tries to decode each part as if it was an `str()`-encoded value. Change the encoding to match the decoding. The only type this matters for is `str`, because `json.dumps` and `str` produce different encodings for `str` values. Remove `none_type` from the list of encodable types since, to my knowledge, there's no way to encode a `None` value as a `multipart/form-data` part in a way that DRF will understand.
55bec58
to
185ae38
Compare
FWIW, I think we should eventually phase out support for AFAICS, the only advantage this format has over JSON is that Django makes it easy to handle arbitrary-length file uploads (since it saves the incoming files in a temporary directory). But we already support TUS, which also lets clients upload such files. On the other hand, |
@@ -126,8 +126,8 @@ class ApiClient(object): | |||
self.default_headers['User-Agent'] = value | |||
|
|||
def _serialize_post_parameter(self, obj): | |||
if isinstance(obj, (str, int, float, none_type, bool)): | |||
return ('', json.dumps(obj), 'application/json') | |||
if isinstance(obj, (str, int, float, bool)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the exclusion of None
mean SDK users will obtain errors when trying to send None
values in POST requests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. But I don't think you can send None
values as multipart/form-data
anyway, so better to fail early.
I may be wrong, by comparing to JSON, multipart/form-data should allow passing binary data with no extra encoding overhead, while in JSON we need to encode the data using escape sequences and text characters. |
Yeah, fair point. Still, TUS also lets you do this, so we don't need |
Probably, we still have at least 1 use case when we need multipart/form-data - it is when we send multiple files in a single request during task data uploading (both |
Yeah, it's true. Perhaps we just need to be careful with the parameters that we accept alongside file uploads, and only use parameter types that can be transferred by simple serialization. |
It seems like the only working way now, actually. If we will split the parameters by requests and only send the required params (which is only the Upd.: I have an idea that for files, can we encode them into some reversible ASCII-based representation (e.g. base64) for transfer. |
…vat-ai#5479) Django REST Framework ignores the Content-Type on request body parts, so it doesn't know that they are JSON-encoded. Instead, it just tries to decode each part as if it was an `str()`-encoded value. Change the encoding to match the decoding. The only type this matters for is `str`, because `json.dumps` and `str` produce different encodings for `str` values. Remove `none_type` from the list of encodable types since, to my knowledge, there's no way to encode a `None` value as a `multipart/form-data` part in a way that DRF will understand.
Django REST Framework ignores the Content-Type on request body parts, so it doesn't know that they are JSON-encoded. Instead, it just tries to decode each part as if it was an
str()
-encoded value.Change the encoding to match the decoding. The only type this matters for is
str
, becausejson.dumps
andstr
produce different encodings forstr
values.Remove
none_type
from the list of encodable types since, to my knowledge, there's no way to encode aNone
value as amultipart/form-data
part in a way that DRF will understand.Motivation and context
This is a follow-up to #5058. Replaces #5240.
How has this been tested?
API unit tests.
Checklist
develop
branch[ ] I have updated the documentation accordingly[ ] I have added tests to cover my changes[ ] I have linked related issues (read github docs)[ ] I have increased versions of npm packages if it is necessary (cvat-canvas,cvat-core, cvat-data and cvat-ui)
License
Feel free to contact the maintainers if that's a concern.