load-balancer / app.py
ChandimaPrabath's picture
patch 2
83371d8
from fastapi import FastAPI, HTTPException, Request, Query
from fastapi.responses import JSONResponse
import logging
import os
from typing import List
from LoadBalancer import LoadBalancer
from utils import is_valid_url
from urllib.parse import unquote
CACHE_DIR = os.getenv("CACHE_DIR")
TOKEN = os.getenv("TOKEN")
REPO = os.getenv("REPO")
app = FastAPI()
@app.on_event("startup")
async def startup_event():
global load_balancer
load_balancer = LoadBalancer(cache_dir=CACHE_DIR, token=TOKEN, repo=REPO)
@app.get("/")
def greet_json():
return {"Version": load_balancer.version}
@app.post("/api/post/register")
async def register_instance(request: Request):
try:
data = await request.json()
if not data or "url" not in data:
return JSONResponse(content={"error": "No URL provided"}, status_code=400)
url = data["url"]
if not is_valid_url(url):
return JSONResponse(content={"error": "Invalid URL"}, status_code=400)
# Register the instance
load_balancer.register_instance(url)
logging.info(f"Instance registered: {url}")
return JSONResponse(content={"message": f"Instance {url} registered successfully"}, status_code=200)
except Exception as e:
logging.error(f"Error registering instance: {e}")
return JSONResponse(content={"error": "Failed to register instance"}, status_code=500)
@app.get("/api/get/file_structure")
async def get_file_structure():
return load_balancer.file_structure
@app.get("/api/get/music/store")
async def get_music_store():
return load_balancer.MUSIC_STORE
@app.get("/api/get/music/all")
async def get_all_music_api(
page: int = Query(None, ge=1), # Default to None, but must be at least 1 if provided
limit: int = Query(None, ge=1, le=100) # Default to None, but must be between 1 and 100 if provided
):
# Fetch all music files from the load balancer
all_music = load_balancer.get_all_music()
# If pagination parameters are not provided, return all music
if page is None or limit is None:
return {"total_files": len(all_music), "files": all_music}
# Calculate the starting index and the end index for pagination
start_index = (page - 1) * limit
end_index = start_index + limit
# Handle the case where the requested page exceeds available files
if start_index >= len(all_music):
raise HTTPException(status_code=404, detail="No more files available for the requested page.")
# Get the paginated music files
paginated_music = all_music[start_index:end_index]
# Prepare the response
return {
"page": page,
"limit": limit,
"total_files": len(all_music),
"files": paginated_music
}
@app.get('/api/get/instances')
async def get_instances():
return load_balancer.instances
@app.get('/api/get/instances/health')
async def get_instances_health():
return load_balancer.instances_health
@app.get("/api/get/music/{file_name}")
async def get_music_api(file_name: str):
"""Endpoint to get the music file by title."""
# Decode the file_name from URL encoding
decoded_file_name = unquote(file_name)
if not decoded_file_name:
raise HTTPException(status_code=400, detail="file_name parameter is required")
# Check if the music file is already cached
if decoded_file_name in load_balancer.MUSIC_STORE:
url = load_balancer.MUSIC_STORE[decoded_file_name]
return JSONResponse(content={"url": url})
music_path = load_balancer.find_music_path(decoded_file_name)
if not music_path:
raise HTTPException(status_code=404, detail="Music file not found")
# Start the download in an instance
response = load_balancer.download_music_to_best_instance(file_name=decoded_file_name)
if response:
return JSONResponse(content=response)
@app.get('/api/get/category/all')
async def get_categories():
return load_balancer.get_all_categories()
@app.get("/api/get/category/{category}")
async def get_all_from_a_category(
category: str,
page: int = Query(1, ge=1), # Default to page 1, minimum value is 1
limit: int = Query(10, ge=1, le=100) # Default limit is 10, max limit is 100
):
if not category:
raise HTTPException(status_code=400, detail="category parameter is required")
# Fetch all files from the category
all_files = load_balancer.get_files_from_category(category)
# Calculate the starting index and the end index for pagination
start_index = (page - 1) * limit
end_index = start_index + limit
# Get the paginated files
paginated_files = all_files[start_index:end_index]
# Prepare the response
return {
"page": page,
"limit": limit,
"total_files": len(all_files),
"files": paginated_files
}