import base64 from typing import Annotated, Optional from fastapi import (Body, FastAPI, File, Form, HTTPException, UploadFile, status) from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from pydantic import AnyHttpUrl, UrlConstraints from config import settings import uvicorn from utils.audio_utils import AudioUtils from utils.caption_utils import ImageCaptioning from utils.image_utils import UrlTest from utils.topic_generation import TopicGenerator app = FastAPI( title=settings.PROJECT_NAME, ) # CORS if settings: app.add_middleware( CORSMiddleware, allow_origins='*', allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) topic_generator = TopicGenerator() img_caption = ImageCaptioning() audio_utils = AudioUtils() utils = UrlTest() @app.get("/") def root(): return {"message": "Welcome To Rediones API"} @app.get("/health") def health(): return {"message": "OK"} @app.post("/topicgen") def generate_topic( img: UploadFile = File( default=None, description="Image file. It mutually excludes ImgUrl", # regex=r"^.+\.(jpg|png|jpeg)$" ), text: Annotated[Optional[str], Form()] = None, img_url: Annotated[ Optional[AnyHttpUrl], UrlConstraints(allowed_schemes=["https"]), Form(description=( "Image url only accepts https scheme. It mutually excludes Img" )) ] = None, ): if img_url and img: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Only one of image_url or img can be accepted" ) # if only text is provided elif text is not None and img is None and img_url is None: generated_topics = topic_generator.generate_topics(text) return {"topics": generated_topics} # if image/image_url is provided with or without text elif img or img_url or text: img_file_object = None # initialize img_file_object # decide whether img or img_url is provided if img: # image file must be ended with .jpg, .png, .jpeg if not str(img.filename).endswith( (".jpg", ".png", ".jpeg") ): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Image file must be ended with .jpg, .png, .jpeg" ) img_file_object = img.file elif img_url: img_file_object = utils.load_image(img_url) # decide whether text is provided if text is None: capt = img_caption.get_caption(img_file_object) else: capt = str(text) + "." + img_caption.get_caption(img_file_object) generated_topics = topic_generator.generate_topics(capt) return {"topics": generated_topics} else: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="enter text or image. " "imageurl and img are mutually exclusive" ) @app.post("/audioverse") def generate_audio( text: Annotated[str, Body(description="Text to be transcribed.")] ): if text is not None: audio_bytes = audio_utils.speak(text) audio_base64 = base64.b64encode(audio_bytes).decode("utf-8") return JSONResponse(content={"audio_base64": audio_base64}) @app.post("/transcribe") def transcribe_audio( audio: UploadFile = File( default=None, description="Audio file to be transcribed." ) ): if audio is not None: audio_transcribe = audio_utils.improved_transcribe(0.8, audio_file=audio.file) return JSONResponse(content={"audio_transcription": audio_transcribe}) if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=8000)