It seems I can’t get to understand this topic, since it’s a variation of this other old post of mine.
Unfortunately that solution cannot be applied here.
What I am trying to accomplish is to upload a file from a remote web-page to my App, submitting it as a form action POST.
So I have written for testing this very simple upload form:
<!DOCTYPE HTML>
<html>
<head>
<title>My Upload</title>
</head>
<body>
<form action="https://my-app-name.anvil.app/_/api/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="name_of_file"/>
<input type="submit" value="Upload"/>
</form>
</body>
</html>
I use it to upload a 1-line-txt file to my api endpoint, that is this:
@anvil.server.http_endpoint(path="/upload")
def upload(**querystring):
request = anvil.server.request
result = 'QUERYSTRING:{qs}\nPATH:{path}\nQUERY:{query}\nFORM:{form}\nHEADERS:{headers}\nBODY:\n-content type:{content_type}\n-length:{length}\n-name:{name}\n-getbytes:{bytestr}\nBODY_JSON:{body_json}'.format(
qs = querystring,
path = request.path,
query = request.query_params,
form = request.form_params,
headers = request.headers,
content_type = request.body.content_type,
length = request.body.length,
name = request.body.name,
bytestr = request.body.get_bytes(),
body_json = request.body_json
)
return(result)
When I fire the “upload” button in the html form, the http endpoint is hit and the response I get in the browser is:
QUERYSTRING:{}
PATH:/upload
QUERY:{}
FORM:{}
HEADERS:{'origin': 'https://my-app-name.anvil.app', 'sec-fetch-site': 'same-origin', 'host': 'platform-server:3000', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36', 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryp6DsIiMuewtzMNii', 'cookie': 'anvil-test-cookie=true; anvil-test-cookie=true; _ga=GA1.2.xxxx.yyyy; _gid=GA1.2.xxxx.yyyy; ring-session=xxxxxyyyy', 'content-length': '206', 'upgrade-insecure-requests': '1', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'accept-language': 'it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7', 'ssl-client-verify': 'NONE', 'sec-fetch-dest': 'empty', 'x-forwarded-for': 'x.x.x.x', 'accept-encoding': 'gzip, deflate, br', 'sec-fetch-mode': 'same-origin', 'x-real-ip': 'x.x.x.x', 'cache-control': 'max-age=0', 'anvil-host': 'my-app-name.anvil.app'}
BODY:
-content type:multipart/form-data; boundary=----WebKitFormBoundaryp6DsIiMuewtzMNii
-length:206
-name:None
-getbytes:b'------WebKitFormBoundaryp6DsIiMuewtzMNii\r\nContent-Disposition: form-data; name="name_of_file"; filename="file.txt"\r\nContent-Type: text/plain\r\n\r\nMy file contents\r\n------WebKitFormBoundaryp6DsIiMuewtzMNii--\r\n'
BODY_JSON:None
My questions are again:
- why are form parameters not available in
request.form_params
? - why is
request.body_json
empty? - in general why
request.body
is the only attribute with meaningful content? I don’t think the standard way to do this is to parse the MIME multipart structure to get the file.
Thanks for your help.