ai-audio-books / app.py
bl4dylion's picture
add auth to the gradio
3a9a0d8
raw
history blame
3.73 kB
import os
from pathlib import Path
from typing import List
import gradio as gr
from dotenv import load_dotenv
from langchain_community.document_loaders import PyPDFLoader
load_dotenv()
from src.builder import AudiobookBuilder
from src.config import logger, FILE_SIZE_MAX
def get_auth_params() -> List[tuple[str, str]]:
users = os.environ["AUTH_USERS"].split(",")
passwords = os.environ["AUTH_PASS"].split(",")
auth_list = [(u, passwords[0] if len(passwords) == 1 else p) for u, p in zip(users, passwords)]
return auth_list
def parse_pdf(file_path):
"""Parse the PDF file and return the text content."""
loader = PyPDFLoader(file_path)
documents = loader.load()
return "\n".join([doc.page_content for doc in documents])
def load_text_from_file(uploaded_file):
# Save the uploaded file temporarily to check its size
temp_file_path = uploaded_file.name
if os.path.getsize(temp_file_path) > FILE_SIZE_MAX * 1024 * 1024:
raise ValueError(
f"The uploaded file exceeds the size limit of {FILE_SIZE_MAX} MB."
)
if uploaded_file.name.endswith(".txt"):
with open(temp_file_path, "r", encoding="utf-8") as file:
text = file.read()
elif uploaded_file.name.endswith(".pdf"):
text = parse_pdf(temp_file_path)
else:
raise ValueError("Unsupported file type. Please upload a .txt or .pdf file.")
return text
async def respond(text: str, uploaded_file) -> tuple[Path | None, str]:
if uploaded_file is not None:
try:
text = load_text_from_file(uploaded_file=uploaded_file)
except Exception as e:
logger.exception(e)
return (None, str(e))
builder = AudiobookBuilder()
audio_fp = await builder.run(text=text)
return audio_fp, ""
def refresh():
return None, None, None # Reset audio output, error message, and uploaded file
with gr.Blocks(title="Audiobooks Generation") as ui:
gr.Markdown("# Audiobooks Generation")
with gr.Row(variant="panel"):
text_input = gr.Textbox(label="Enter the book text", lines=20)
# Add a file upload field for .txt and .pdf files
file_input = gr.File(
label="Upload a text file or PDF", file_types=[".txt", ".pdf"]
)
with gr.Row(variant="panel"):
audio_output = gr.Audio(label="Generated audio", type="filepath")
error_output = gr.Textbox(
label="Error Messages", interactive=False, visible=False
) # Initially hidden
submit_button = gr.Button("Submit")
submit_button.click(
fn=respond,
inputs=[text_input, file_input], # Include the uploaded file as an input
outputs=[
audio_output,
error_output,
], # Include the audio output and error message output
)
refresh_button = gr.Button("Refresh")
refresh_button.click(
fn=refresh,
inputs=[],
outputs=[
audio_output,
error_output,
file_input,
], # Reset audio output, error message, and uploaded file
)
# Hide error message dynamically when input is received
text_input.change(
fn=lambda _: gr.update(visible=False), # Hide the error field
inputs=[text_input],
outputs=error_output,
)
file_input.change(
fn=lambda _: gr.update(visible=False), # Hide the error field
inputs=[file_input],
outputs=error_output,
)
# To clear error field when refreshing
refresh_button.click(
fn=lambda _: gr.update(visible=False), # Hide the error field
inputs=[],
outputs=error_output,
)
ui.launch(auth=get_auth_params())