File upload via Base64 return 400 'bad request'. Following the instructions here:
https://docs.directus.io/api/reference.html#using-base64-content
Execute the python code. Make sure you put 'picture.jpeg' file in the script path.
import requests
import json
import base64
with open('picture.jpeg', "rb") as f:
data = base64.b64encode(f.read()).decode('utf-8')
payload = {};
payload['filename'] = f'picture.jpeg'
payload['data'] = data
jsonPayload = json.dumps(payload)
response = requests.post('https://<apibase>/public/_/files?access_token=<your token>', data = jsonPayload)
Response should be 200.
Response is 400.
@dur41d HTTP 400 means Bad Request. I think that base64.b64encode(f.read()) should already suffice. .decode('utf-8') might not be required, because base64 encoding is no UTF-8 encoding. It's even unlikely, that wrong encoding would cause the request to fail (except that the uploaded base64 might not be decode-able anymore), but it seems to be the form of the payload. Since Requests 2.4.2 one can directly pass a json parameter:
data = base64.b64encode(f.read())
payload = {"filename": "picture.jpeg", "data": data}
response = requests.post("https://<apibase>/public/_/files?access_token=<your token>", json=payload)
PS: It is recommend to set /public as the web-root, which also results in shorter URL.
You're right. This code works:
import requests
import json
import base64
with open('picture.jpeg', "rb") as f:
data = base64.b64encode(f.read()) # .decode('utf-8')
payload = {}
payload['filename'] = f'picture.jpeg'
payload['data'] = data
# jsonPayload = json.dumps(payload)
response = requests.post('https://<apibase>/api/public/_/files?access_token=<token>', data = payload)
Regarding changing the root, i'm using a shared host so I can't do that. We discussed this at length in
https://github.com/directus/api/issues/636
I'm closing this issue.
@dur41d and @syslogic — would adding anything to the Docs help others avoid this issue?
@dur41d even on a shared hosting, this should be possible, at least while the control-panel permits setting the web-root on a per-domain or a per-subdomain basis (access to this capability may vary from provider to provider). I've already seen this feature request (which is about setting it to another location than / or public/ ) and was thinking about aliasing the location; this also seems rather hosting-configuration related, than it would be directly related to whatever script being deployed there. I would have to create a test-install once, to see if it affects the functionality.
@benhaynes working code-examples in the most common languages might be the best possible support (or example client implementations, which utilize the existing SDK libraries). because ordinary, when knowing how the output shall look alike, this is something one can produce - however, this might still require some trial & error to get there... that's why proven to be working examples would provide a good reference - and example clients would provide starting-points for custom development.
That's a great point @syslogic — we're working through a few priority tickets at the moment, but after that we'll definitely focus more on example code in the Docs (and example code repos). 👍
@syslogic I'm using nearlyfreespeed.net and I don't see that I can change the document root. But in any case I don't want to because I want to use the same site for the api, app and the frontend website and not a separate site for each. I think the api path being hard-coded to public is inflexible and not necessary and does not play well with shared hosts.