Frontend = React, backend = FastApi. How can I simply send an image from the frontend, and have the backend return the result back to the app?
This is my front end look like
// pages/about.js
import React, {useState, useRef} from "react";
import "../App.css";
const StitchImage = () => {
const [image1, setImage1] = useState(null);
const [image2, setImage2] = useState(null);
const inputRef1 = useRef();
const inputRef2 = useRef();
const [stitchedImage,setStitchedImage] = useState(null);
const handleImage1Change = (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onloadend = () => {
console.log(file)
setImage1(reader.result);
};
reader.readAsDataURL(file);
}
};
const handleImage2Change = (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onloadend = () => {
setImage2(reader.result);
};
reader.readAsDataURL(file);
}
};
const removeImage1 = () => {
setImage1(null);
if (inputRef1.current) {
inputRef1.current.value = ''; // Resetting the input field value
}
};
const removeImage2 = () => {
setImage2(null);
if (inputRef2.current) {
inputRef2.current.value = ''; // Resetting the input field value
}
};
const stitchingImages = async () => {
if (!image1 || !image2) {
// Handle case where both images are not selected
window.alert('Please select both images before stitching.');
return;
}
const formData = new FormData();
formData.append('image1', image1);
formData.append('image2', image2)
try {
const response = await fetch('/process-images', {
method: 'POST',
body: formData
});
if(!response.ok) {
throw new Error('Image stitching failed');
}
const data = await response.json();
setStitchedImage(data.stitchedImage);
} catch (error) {
let message = error.message;
if(error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
message = error.response.data.message;
} else if (error.request) {
// The request was made but no response was received
message = 'No response received';
} else {
// Something else happened in making the request
message = error.message;
}
// Handle error
window.alert(message);
}
};
return (
<div className="image-uploader">
<div className="image-container">
<h2>Image 1</h2>
<input type="file" accept="image/jpg, image/jpeg, image/png" onChange={handleImage1Change} ref={inputRef1}/>
{image1 && (
<div>
<img src={image1} alt="" className="preview-img" />
<br/>
<button onClick={removeImage1}>Remove Image 1</button>
</div>
)}
</div>
<div className="image-container">
<h2>Image 2</h2>
<input type="file" accept="image/jpg, image/jpeg, image/png" onChange={handleImage2Change} ref={inputRef2}/>
{image2 && (
<div>
<img src={image2} alt="" className="preview-img" />
<br/>
<button onClick={removeImage2}>Remove Image 2</button>
</div>
)}
</div>
<button onClick={stitchingImages} className="stitch-button">Stitch Images</button>
{stitchedImage && (
<img src={stitchedImage} alt="Stitched" />
)}
</div>
);
};
export default StitchImage;
And back end:
import shutil
from fastapi import FastAPI, File, HTTPException, UploadFile, Form
import os
import subprocess
from pydantic import ValidationError
app=FastAPI()
def validate_file_type(filename: str):
allowed_extensions = ('.jpg', '.jpeg', '.png')
ext = os.path.splitext(filename)[1]
if ext.lower() not in allowed_extensions:
raise HTTPException(status_code=422, detail="Only JPEG and PNG files allowed")
@app.post("/process-images")
async def process_images(img1: UploadFile=File(...), img2:UploadFile=File()):
try:
validate_file_type(img1.filename)
validate_file_type(img2.filename)
# Process image 1
with open(f"{img1.filename}", "wb") as buffer:
shutil.copyfileobj(img1.file, buffer)
# Process image 2
with open(f"{img2.filename}", "wb") as buffer:
shutil.copyfileobj(img2.file, buffer)
# Perform the desired operation on the images here
# Replace 'result' with the actual result of the operation
return {"message": "Images processed successfully"}
except ValidationError as e:
raise HTTPException(status_code=422, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail="Internal server error")
The server still return 422 Unprocessable Entity when i sending the images
Try to change the formData but it seems doesn't work
image1andimage2in the javascript, while you've named themimg1andimg2in your endpoint. Look at the body of the 422 error to get the actual error and description from FastAPIwhenever code repeats create a separate component. I have added the solution, have a look.