Use FastAPI with VueJS

April 6, 2025
You will learn how to make a simple backend in fastapi and connect it to a simple vuejs frontend.
What you will need:
- FastAPI - a web framework for building APIs with Python based on standard Python type hints.
- Vue CDN - my frontend framework of choice
- Uvicorn - an ASGI web server implementation for Python.
- Tailwind CDN (optional) - for fast CSS styling
Project setup
app/
server/
main.py
assets/
image.jpeg
image.png
client/
index.html
The frontend and backend
VS Code's live server uses 5500 so that was added. You will need to add the origin of your frontend.
python
from typing import Union
import os
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import base64
app = FastAPI()
# The origins allowed to hit this server
origins = [
"http://localhost.upskil.dev",
"https://localhost.upskil.dev",
"http://localhost",
"http://localhost:8080",
"http://localhost:5500",
"http://127.0.0.1:5500"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
class FileLister():
@classmethod
def get_files(cls,directory,extensions):
all_files = [f for f in os.listdir(directory) if f.endswith(extensions)]
return all_files
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/images")
def get_images():
all_images = FileLister.get_files('./assets',('.png','.PNG','.jpg','.JPG','.webp','.WEBP','.gif','.jpeg'))
encoded_images = []
for i in all_images:
with open("./assets/"+i, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
encoded_images.append(encoded_string)
return {"images": encoded_images}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
html
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>FastAPI + Vue</title>
<script src='https://cdn.tailwindcss.com'></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body id="app" class="bg-gray-200">
<div>
<nav class="bg-white p-4 w-full">
<ul class="flex justify-between w-full">
<li>{{message}}</li>
<li>FastAPI + Vue</li>
<li><button @click="fetchData()" class="rounded-lg bg-black text-white px-4 py-2">Get Images</button>
</li>
</ul>
</nav>
<div class="container mx-auto w-full p-10">
<main class="w-full">
<div>
<h1>MAIN AREA</h1>
<div v-if="response_data" class="mt-4 flex flex-wrap gap-4">
<img class="object-cover w-64 h-64 rounded-lg" v-for="i in response_data.images"
:src="'data:image/png;base64, '+i">
</div>
</div>
</main>
</div>
</div>
<script>
const { createApp, ref } = Vue
createApp({
setup() {
const message = ref('Home');
const response_data = ref();
async function fetchData() {
try {
const response = await fetch("http://127.0.0.1:8000/images");
if (!response.ok) {
throw new Error(response.statusText)
}
const data = await response.json();
console.log(data)
response_data.value = data
} catch (error) {
console.log(error)
}
}
return {
message, response_data, fetchData
}
}
}).mount('#app')
</script>
</body>
</html>
TIP
You will need to create the assets
directory at the same level as your main.py
file and add images to it
Start the FastAPI server
Navigate to your server
folder and run the FastAPI server from the terminal
cd server
uvicorn main:app --reload
Open index.html
using a server
I used vscode's live server to open the index.html
file. You can do this by right clicking on index.html
and then clicking Open with Live Server.