The question is published on by Tutorial Guruji team.
I try to upload an image from my react-admin
app to FastAPI using axios. The ImageInput
component returns a File
object which I cast to a Blob
and try to upload using axios
.
The API client I am using has been generated by orval.
The response I receive after sending the POST
:
{ "detail":[ { "loc":[ "body", "file" ], "msg":"Expected UploadFile, received: <class 'str'>", "type":"value_error" } ] }
axios
request function:
/** * @summary Create Image */ export const createImage = ( bodyCreateImageImagesPost: BodyCreateImageImagesPost, options?: AxiosRequestConfig ): Promise<AxiosResponse<Image>> => { const formData = new FormData(); formData.append( "classified_id", bodyCreateImageImagesPost.classified_id.toString() ); formData.append("file", bodyCreateImageImagesPost.file); return axios.post(`/images`, formData, options); };
axios
request headers:
POST /images HTTP/1.1 Host: localhost:8000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0 Accept: application/json, text/plain, */* Accept-Language: pl,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Authorization: bearer xxx Content-Type: multipart/form-data; boundary=---------------------------41197619542060894471320873154 Content-Length: 305 Origin: http://localhost:3000 DNT: 1 Connection: keep-alive Referer: http://localhost:3000/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-site Sec-GPC: 1
Request data object:
{ "classified_id": 2, "file": { "rawFile": {...}, "src": "blob:http://localhost:3000/9826efb4-875d-42f9-9554-49a6b13204be", "name": "Screenshot_2019-10-16-18-04-03.png" } }
FastAPI endpoint:
def create_image( classified_id: int = Form(...), file: UploadFile = File(...), db: Session = Depends(get_db), user: User = Security(manager, scopes=["images_create"]), ) -> Any: # ...
In the “Network” section of the developer tools in a browser, it shows the file
field as [object Object]
but I guess that’s just a problem with no string representation of the Blob
?
When I try to upload an image through the Swagger UI, it works as expected and the curl
request looks like this:
curl -X 'POST' 'http://localhost:8000/images' -H 'accept: application/json' -H 'content-length: 3099363' -H 'Authorization: Bearer xxx' -H 'Content-Type: multipart/form-data' -F 'classified_id=2' -F 'file=@Screenshot_2019-10-16-18-04-03.png;type=image/png'
Any ideas what is wrong in here? How should the proper axios
request look like?
Answer
Use as follows (change the URL endpoint’s name, as well as the “Accept” header, to the ones you are using):
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script type="text/javascript"> function uploadFile() { var formData = new FormData(); var fileInput = document.getElementById('fileInput'); if (fileInput.files[0]) { formData.append("classified_id", 2); formData.append("file", fileInput.files[0]); axios({ method: 'post', url: '/upload', data: formData, headers: { 'Accept': 'application/json', 'Content-Type': 'multipart/form-data' }, }) .then(function(response) { console.log(response); }) .catch(function(response) { console.log(response); }); } } </script> <input type="file" id="fileInput" name="file"><br> <input type="button" value="submit" onclick="uploadFile()">