Specifically, I want the below example to work:
app.py
from fastapi import FastAPI,File,UploadFile,Form,Body
import uvicorn
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/hello/{name}")
async def say_hello(name: str):
return {"message": f"Hello {name}"}
@app.post("/jsk")
async def save_image_meta(farm_name: str = Form(...), files: UploadFile = File(...)):
print('*'*100)
return {
"farm_name": farm_name
}
if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=8088, reload=True)
If this is not a proper way for a POST request, please advise me how to select required columns from an uploaded image file in FastAPI.
test.py
import base64
import hmac
import json
import requests
def parse_params_to_str(params):
url = "?"
for key, value in params.items():
url = url + str(key) + '=' + str(value) + '&'
return url[1:-1]
def hash_string(qs, secret_key):
mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(qs, encoding='utf-8'), digestmod='sha256')
d = mac.digest()
validating_secret = str(base64.b64encode(d).decode('utf-8'))
return validating_secret
def sample_request():
access_key = "dfaa65a6-ee25-4b03-916b-bedb9095-35f9-4485-a72e-5da4e161a12b"
secret_key = "GWpnn56bUOnCedhpiUWYJl9dtZ3WllWtUeBUGQva"
qs = dict(key=access_key)
header_secret = hash_string(parse_params_to_str(qs), secret_key)
url = f"http://127.0.0.1:8088/jsk"
headers = {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json',
'secret': header_secret
}
file = "/Users/jskim/Downloads/111111.jpg"
files = {'files': open(file, 'rb')}
payload = {"farm_name": "11111"}
res = requests.post(url, data=payload, headers=headers, files=files)
return res
sample_request()
I am getting a 400 Bad Request
error.
If this is not a proper way for a POST request, please advise me how to select required columns from an uploaded image file in FastAPI.
You should not define the Content-Type multipart/form-data
header yourself. The requests
library takes care of this automatically by defining the boundary. If you set this header yourself, requests
will not do it and your server will not know what boundary to expect (unless you decide to also set the boundary yourself).
To work your header should be without the content-type:
headers = {
'Accept': 'application/json',
secret: header_secret
}