[Python] 422 Unprocessable Entity error in FastAPI when I try to upload an image using React...

Discussão em 'Python' iniciado por Stack, Outubro 6, 2024.

  1. Stack

    Stack Membro Participativo

    The following code works perfectly when I hit this API using Swagger UI. However, it fails to perform when it is being hit from a react frontend, showing status code 422 unprocessable entity. Below is my FastAPI endpoint:

    @post.post('/post')
    async def create_post(post_text: str, image: bytes = File(None), token: str = Depends(oauth2_scheme), db: Session = Depends(database.get_db)):
    user_info = await services.get_user_info(token)
    username = user_info["username"]
    print(username)
    image_url = None
    if image:
    # Generate a unique filename for the image
    image_filename = f"{username}_{uuid.uuid4().hex}.jpg"
    # print(image_filename)

    # Save the image to bytes and send to MinIO bucket
    # image_bytes = await image.read()
    image_bytes = base64.b64decode(image.split(",")[1])

    minio_client.put_object(
    "minilinkedindistributed",
    image_filename,
    io.BytesIO(image_bytes),
    length=len(image_bytes),
    content_type="image/jpeg"
    )

    # Construct the image URL based on MinIO server URL and bucket name
    image_url = f"http://127.0.0.1:9000/minilinkedindistributed/{image_filename}"
    print(image_url)
    elif image is None or image.filename == '':
    raise HTTPException(status_code=400, detail='Invalid or empty image file')
    # Create the post
    new_post = services.make_post(db, username, post_text, image_url)

    headers = {"Authorization": f"Bearer {token}"}

    # Get all users (except the one who posted)
    async with httpx.AsyncClient() as client:
    response = await client.get("http://127.0.0.1:8000/api/v1/all_users_except_poster", headers=headers)

    if response.status_code == 200:
    all_users_except_poster = response.json()
    else:
    raise HTTPException(status_code=response.status_code, detail="Failed to fetch users from user service")

    # Create a notification for each user
    for user_to_notify in all_users_except_poster:
    notification_data = {
    'notification_text': f"{username} made a new post...",
    'pid' : new_post.id,
    'username' : user_to_notify["username"],
    'notification_datetime' : datetime.utcnow().isoformat(),
    'is_read' : False
    }


    async with httpx.AsyncClient() as client:
    response = await client.post("http://127.0.0.1:8002/api/v1/notification", json=notification_data, headers=headers)

    if response.status_code != 200:
    raise HTTPException(status_code=response.status_code, detail="Failed to send notification")


    return{"message" : new_post}


    and below is my react component:

    const HomePage = () => {
    const [posts, setPosts] = useState([]);
    const [loggedIn, setLoggedIn] = useState(false);
    const [postText, setPostText] = useState('');
    const [selectedImage, setSelectedImage] = useState(null);
    const [notifications, setNotifications] = useState([]);
    const navigate = useNavigate();

    useEffect(() => {
    const access_token = localStorage.getItem('access_token');
    if (access_token) {
    setLoggedIn(true);
    fetchPosts(access_token);
    }
    }, []);


    const handlePostTextChange = (event) => {
    setPostText(event.target.value);
    };

    const handleImageChange = (event) => {
    setSelectedImage(event.target.files[0]);
    };

    const handleSubmitPost = async () => {
    const formData = new FormData();
    formData.append('post_text', postText); // Make sure 'postText' holds the user's post text
    if (selectedImage) {
    formData.append('image', selectedImage, selectedImage.name); // Make sure 'selectedImage' holds the user's selected image
    }else console.log('Invalid or empty image file');
    console.log("Post Text:", postText);
    console.log("Selected Image:", selectedImage);
    console.log('FormData:', formData);

    const access_token = localStorage.getItem('access_token');

    // Make a POST request to create a new post
    try {
    const response = await axios.post(`${API_BASE_URL}/post`, formData, {
    headers: {
    Authorization: `Bearer ${access_token}`,
    'Content-Type': 'multipart/form-data', // Set the correct content type for the form data
    },
    });

    // Refresh the posts after successful submission
    fetchPosts(access_token);

    } catch (error) {
    console.error('Error submitting post:', error.response);
    }

    };


    Stuck here, any solution will help. Thank you.

    Continue reading...

Compartilhe esta Página