pycloudinary
pycloudinary copied to clipboard
transformation name with spaces causes 400 error
Making a call to get transformations, some of them come back with spaces in the name like this:
{u'allowed_for_strict': False,
u'name': u'fl_progressive,t_primary/t_t_primary@2x jpg.t_primary@2x jpg.display@2x',
u'used': False},
Now trying to use that (ignoring issue #41 for now), generates a 400 server error:
In [10]: name = 'fl_progressive,t_primary/t_t_primary@2x jpg.t_primary@2x jpg.display@2x'
In [11]: cloudinary.api.transformation(name)
---------------------------------------------------------------------------
GeneralError Traceback (most recent call last)
<ipython-input-11-031ddf1dde0b> in <module>()
----> 1 cloudinary.api.transformation(name)
.../venv/lib/python2.7/site-packages/cloudinary/api.pyc in transformation(transformation, **options)
129 def transformation(transformation, **options):
130 uri = ["transformations", transformation_string(transformation)]
--> 131 return call_api("get", uri, only(options, "max_results"), **options)
132
133 def delete_transformation(transformation, **options):
.../venv/lib/python2.7/site-packages/cloudinary/api.pyc in call_api(method, uri, params, **options)
225 # Error is parsing json
226 e = sys.exc_info()[1]
--> 227 raise GeneralError("Error parsing server response (%d) - %s. Got - %s" % (response.code, body, e))
228
229 if "error" in result:
GeneralError: Error parsing server response (400) - . Got - No JSON object could be decoded
The fix it seems is to renencode the name using url encoding:
In [12]: name = 'fl_progressive,t_primary/t_t_primary@2x%20jpg.t_primary@2x%20jpg.display@2x'
In [13]: cloudinary.api.transformation(name)
Out[13]:
{u'allowed_for_strict': False,
u'derived': [],
u'info': [{u'flags': [u'progressive'], u'transformation': [u'primary']},
{u'transformation': [u't_primary@2x jpg', u'display@2x']}],
u'name': u'fl_progressive,t_primary/t_t_primary@2x jpg.t_primary@2x jpg.display@2x',
u'used': False}
Not just transformation name, public ids as well. I had a public_id that ended in a slash and it threw the same errors. Needed to urllib.quote(public_id, '') before sending it. Also public_id (and transformations also) have unicode issues so the full line to fix a public_id is:
public_id = urllib.quote(str(public_id.encode('utf-8')), '')
EXCEPT fetch urls have public ids that you don't escape.
Hi @oppianmatt
I see that the last response is from a while back. Are you still experiencing the issue?
@idobarnoam we're experiencing the issue, it's really painful!
cached_version = cache.get(f'cloudinary_version-preview-{file.key}')
preview_image = cloudinary.CloudinaryImage(
os.path.join(settings.MEDIA_CLOUDINARY_PREFIX, file.key),
version=cached_version,
)
preview_image.url_options.update({
'width': 2500,
'height': 2500,
'crop': 'limit',
'flags': 'attachment',
})
file_dict.update({
'url': preview_image.url, # here we replace `url`. remove this when react-keyed-file-browser is updated
'preview_url': preview_image.url,
})
This produces a URL like;
https://images.onuptick.com/image/upload/s--sQ2RlW0s--/c_limit,fl_attachment,h_2500,w_2500/v1/tesg/properties/40956/public/Annual%20Certification/2018/E%26E%203.JPG
That causes a 400 error,
x-cld-error: public_id (tesg/properties/40956/public/Annual Certification/2018/E&E 3) is invalid
x-request-id: d005f3099039b94b
x-ua-compatible: IE=Edge,chrome=1
The file in S3 is named properties/40956/public/Annual Certification/2018/E&E 4.JPG
Soooo this might not be a problem with escaping the spaces, it's a problem with the &
symbol ...
eg this works, https://images.onuptick.com/image/upload/v1/tesg/properties/40956/public/Annual%20Certification/2018/E_E%204.JPG
There's a few symbols that aren't valid and if it's not a valid public_id it won't auto-upload from the source bucket. I'll go via a support ticket instead as it's not really pycloudinary's problem.
https://support.cloudinary.com/hc/en-us/articles/115001317409--Legal-naming-conventions
FYI We get a little closer double escaping, eg %2526
is escaped back to %26
which is an escaped &
- it's just a remote bucket fetching problem :|
The other non allowed chars are: '?&#\%<>'