Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I display FastAPI's Fileresponse image inside React?

This is my frontend React code:

import * as React from 'react';
import { useEffect, useState } from 'react';

import http from './http-common'; // axios

type Photo = {
  filename: string,
  caption: string,
  tags: string[].
};

const BrowserArticle = ({ filename, caption, tags }: Photo) => {
  const [photoFile, setFile] = useState<string>('');

  useEffect(() => {
    http.get(`/api/getImg/${filename}`)
      .then((response) => {
        console.log(typeof response.data); // console output is 'string'
        console.log(response); // see screenshot below
        setFile(data);
      });
  }, []);

  return (
    <div>
      <img src={photoFile} alt={filename} />
      <div>{caption}</div>
      <div>
        {
           tags.map((tag) => tag)
        }
      </div>
    </div>
  );
};

This is my backend FastAPI code:

from fastapi import FastAPI
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles

app = FastAPI()
app.mount('/static', StaticFiles(directory='static'), name='static')

@app.get('/api/getImg/{image_filename}')
async def get_image(image_filename: str) -> FileResponse:
  return FileResponse(f'./static/uploads/{image_filename}')

CORS has been taken care of. When I send a request to the server, a response was successfully received, but the image could not load. Upon inspection, this is the generated HTML:

enter image description here

When I console.log(data) inside the then() function, this is what I got:

enter image description here

When I tested the API using FastAPI's built-in tool, I verified that the API is successfully returning blob:http://192.168.1.201:8000/0a870a00-cf63-43ef-b952-e49770137fdd

My suspicion is that the data received by axios is the image file itself, so I tried changing my code as follows:

const [photoFile, setFile] = useState<File | null>(null);

// ...

<img src={photoFile === null ? '' : URL.createObjectURL(photoFile)} alt={filename} />

But when I refresh the page, I get TypeError: Failed to execute 'createObjectURL' on 'URL': Overload resolution failed.

I tried searching up how to correctly display an image received from the backend, but the only results I found discussed how to send images to the backend or how to display images being uploaded to server (i.e. display thumbnails of files selected for upload via <input type="file" />. Nothing with regards to this particular problem. Any ideas?

Update: When I did the following, the image is displayed successfully:

<img src={`http://192.168.1.201:8000/api/getImg/${filename}`} alt={filename} />

But that would mean exposing my backend within the generated HTML, and hardcoding the backend IP. Is there a more "proper" way of doing this?

like image 880
thegreatjedi Avatar asked Oct 26 '25 18:10

thegreatjedi


1 Answers

The way I figured out how to do it was by encoding the image as base64 in FastAPI, sending the base64 encoded image to frontend with an API call and rendering the image in the base64 encoded format in React. Here is some of the code for it.
FastAPI code (Remember NOT to use response_model=FileResponse)

with open(imgpath, 'rb') as f:
    base64image = base64.b64encode(f.read())
return base64image

React code.

<img src={data:image/jpeg;base64,${data}} />

Here, ${data} is the base64 encoded image.

like image 84
Alyan Qureshi Avatar answered Oct 28 '25 09:10

Alyan Qureshi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!