4

i'm trying to upload an image from client (reactJS) side to fastAPI using a post method

this is my client side

const [img, setImg] = useState(null)

const onImageUpload = (e) => {
        console.log(e.target.files[0])
        setImg(e.target.files[0])
    }


const handleChange = () => {
        if (!img) setErr("please upload an image")
        else {
            
            let formData = new FormData();
            let token = localStorage.getItem("TikToken")

            formData.append(
                "token",
                token
            )
           
            formData.append(
                "pic",
                img,
                img.name
                )
                

            console.log(formData)
            axios({
                method: 'post',
                url: "http://localhost:8000/profile/pic/",
                data: formData
                
            })
            .then(function(response) {
                console.log(response);
            })

            
        }
    }

and this is my fastAPI function

@app.post("/profile/pic/")
async def setpic(token: str, pic:bytes = File(...)):

    print(pic)
    image = Image.open(io.BytesIO(pic))
    image.show()
    # response = await store_profile_image(form, str(base64.b64encode(form)))
    return "response"
    

i'm gettin error 422 (Unprocessable Entity)

this is the error

Edit:1 Uncaught (in promise) 
AxiosError {message: 'Request failed with status code 422', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
code: "ERR_BAD_REQUEST"
config: {transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}
message: "Request failed with status code 422"
name: "AxiosError"
request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
response: {data: {…}, status: 422, statusText: 'Unprocessable Entity', headers: {…}, config: {…}, …}
[[Prototype]]: Error

what am I doing wrong? and how to fix it?

EDIT:

i checked the error body ( response > data > detail )

i found this

detail: Array(1) 0: 
    loc: (2) ['query', 'token'] 
    msg: "field required" 
    type: "value_error.missing" 

i changed data in axios request to data: { "token" : token, "pic": img}

i got this in the error body

detail: Array(2)
0:
    loc: (2) ['query', 'token']
    msg: "field required"
    type: "value_error.missing"
    [[Prototype]]: Object
1:
    loc: (2) ['body', 'pic']
    msg: "field required"
    type: "value_error.missing"
    [[Prototype]]: Object
length: 2

2
  • 1
    The body of the 422 error will contain the actual error message - i.e. which field is missing or is failing validation. Commented May 12, 2022 at 7:06
  • i edited the question, i added this detail Commented May 12, 2022 at 8:02

1 Answer 1

2

To pass additional parameters with images (i.e. a token) use token:str = Form(...)

Indeed, in order to pass an image, the body must be encoded in multipart/form-data instead of application/json. In this case, the path parameters must be of type File or Form.

This is not a limitation of FastAPI but is part of the HTTP protocol

@app.post("/profile/pic/")
async def setpic(token: str = Form(...), pic:bytes = File(...)):

    print(pic)
    image = Image.open(io.BytesIO(pic))
    image.show()
    # response = await store_profile_image(form, str(base64.b64encode(form)))
    return "response"

And add the header to your axios request

headers: {
   "Content-Type": "multipart/form-data",
 },
Sign up to request clarification or add additional context in comments.

2 Comments

this solved my problem Thank you could you recommend any good documentation that explains more about this ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.