yukee1992's picture
Update app.py
63c8dab verified
import os
import sys
import subprocess
import importlib.util
import uuid
import json
from datetime import datetime
print("=" * 60)
print("πŸš€ STARTING VIDEO PROJECT MANAGER")
print("=" * 60)
# Function to check and install packages
def ensure_package(package_name, import_name=None):
if import_name is None:
import_name = package_name
if importlib.util.find_spec(import_name) is None:
print(f"πŸ“¦ Installing {package_name}...")
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", package_name, "--quiet"])
print(f"βœ… {package_name} installed successfully!")
return True
except Exception as e:
print(f"❌ Failed to install {package_name}: {e}")
return False
else:
print(f"βœ… {package_name} already installed")
return True
# Install required packages
ensure_package("gradio")
ensure_package("supabase")
ensure_package("python-dotenv")
ensure_package("fastapi")
ensure_package("uvicorn")
# Now import after ensuring they're installed
import gradio as gr
from supabase import create_client
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import uvicorn
from threading import Thread
import time
print("\n" + "=" * 60)
# =============================================
# SUPABASE CONNECTION
# =============================================
SUPABASE_URL = os.environ.get("SUPABASE_URL")
SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
print(f"\nπŸ”§ Supabase Configuration:")
print(f" URL: {'βœ… Set' if SUPABASE_URL else '❌ Missing'}")
print(f" Key: {'βœ… Set' if SUPABASE_KEY else '❌ Missing'}")
# Initialize Supabase client
supabase = None
if SUPABASE_URL and SUPABASE_KEY:
try:
supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
print("βœ… Supabase client initialized successfully!")
# Test connection
try:
test_result = supabase.table("projects").select("count", count="exact").limit(1).execute()
print(f"βœ… Database connected! Projects found: {test_result.count}")
except Exception as e:
print(f"⚠️ Database connection test failed: {e}")
except Exception as e:
print(f"❌ Failed to connect to Supabase: {e}")
supabase = None
else:
print("⚠️ Supabase credentials missing - running in memory-only mode")
# =============================================
# CORE FUNCTIONS
# =============================================
def create_project(title, content, tags, image_prompt, channel):
"""Create a new project and save to Supabase"""
print(f"\nπŸ“ Creating project: {title}")
try:
# Generate proper UUID
project_id = str(uuid.uuid4())
folder_name = title.lower().replace(' ', '_').replace('/', '-')[:20]
project_data = {
"project_id": project_id,
"folder_name": folder_name,
"title": title,
"content": content[:5000],
"tags": tags,
"image_prompt": image_prompt,
"channel_details": channel,
"status": "created",
"created_at": datetime.now().isoformat()
}
print(f"πŸ’Ύ Saving project with UUID: {project_id}")
if supabase:
result = supabase.table("projects").insert(project_data).execute()
print(f"βœ… Saved to database!")
return {
"status": "success",
"project_id": project_id,
"folder": folder_name,
"title": title,
"message": "Project created successfully in database!"
}
else:
return {
"status": "memory_only",
"project_id": project_id,
"folder": folder_name,
"title": title,
"message": "Project created in memory only (no database)"
}
except Exception as e:
print(f"❌ Error: {e}")
return {"status": "error", "message": str(e)}
def search_projects(term):
"""Search for projects in Supabase"""
print(f"\nπŸ” Searching for: {term}")
if not supabase:
return [
["Demo Project 1", "memory", datetime.now().strftime("%Y-%m-%d"), "demo_1"],
]
try:
if term and term.strip():
result = supabase.table("projects")\
.select("title, status, created_at, folder_name")\
.ilike("title", f"%{term}%")\
.limit(20)\
.execute()
else:
result = supabase.table("projects")\
.select("title, status, created_at, folder_name")\
.limit(20)\
.order("created_at", desc=True)\
.execute()
projects = []
for p in result.data:
created = p.get("created_at", "")
if created and len(created) > 10:
created = created[:10]
projects.append([
p.get("title", "Untitled"),
p.get("status", "unknown"),
created,
p.get("folder_name", "")
])
return projects if projects else [["No projects found", "", "", ""]]
except Exception as e:
print(f"❌ Search error: {e}")
return [["Error", str(e)[:50], "", ""]]
def health_check():
"""Check system health"""
return {
"status": "healthy",
"supabase_connected": bool(supabase),
"timestamp": datetime.now().isoformat()
}
# =============================================
# CREATE FASTAPI APP
# =============================================
app = FastAPI()
@app.post("/api/create")
async def api_create(request: Request):
"""Direct API endpoint for creating projects"""
try:
data = await request.json()
if "data" in data and len(data["data"]) >= 5:
result = create_project(
data["data"][0],
data["data"][1],
data["data"][2],
data["data"][3],
data["data"][4]
)
return JSONResponse(content=result)
else:
return JSONResponse(
status_code=400,
content={"error": "Invalid data format. Expected: {\"data\": [title, content, tags, prompt, channel]}"}
)
except Exception as e:
return JSONResponse(
status_code=500,
content={"error": str(e)}
)
@app.post("/api/health")
async def api_health():
"""Health check endpoint"""
return JSONResponse(content=health_check())
@app.post("/api/search")
async def api_search(request: Request):
"""Search endpoint"""
try:
data = await request.json()
term = data.get("data", [""])[0] if data.get("data") else ""
result = search_projects(term)
return JSONResponse(content={"results": result})
except Exception as e:
return JSONResponse(
status_code=500,
content={"error": str(e)}
)
@app.get("/")
async def root():
"""Root endpoint redirects to Gradio"""
return {"message": "Video Project Manager API. Use /api/ endpoints. Access UI at /gradio"}
# =============================================
# MOUNT GRADIO APP TO FASTAPI
# =============================================
print("\nπŸ“ Creating Gradio interface...")
with gr.Blocks(title="Video Project Manager") as demo:
gr.Markdown("# 🎬 Video Project Manager")
if supabase:
gr.Markdown("### βœ… Connected to Supabase")
else:
gr.Markdown("### ⚠️ Running in Memory Mode (No Database)")
with gr.Tabs():
with gr.TabItem("πŸ“ Create Project"):
with gr.Row():
with gr.Column():
title_input = gr.Textbox(label="Title", placeholder="Enter video title")
content_input = gr.Textbox(label="Content", lines=3, placeholder="Enter TTS content")
tags_input = gr.Textbox(label="Tags", placeholder="tag1, tag2, tag3")
image_input = gr.Textbox(label="Image Prompt", lines=2, placeholder="Describe images")
channel_input = gr.Textbox(label="Channel Details", value='{"platform": "youtube"}')
create_btn = gr.Button("πŸš€ Create Project", variant="primary")
with gr.Column():
output = gr.JSON(label="Result")
with gr.TabItem("πŸ” Search"):
search_input = gr.Textbox(label="Search Term", placeholder="Enter search term")
search_btn = gr.Button("πŸ” Search", variant="secondary")
results = gr.Dataframe(
headers=["Title", "Status", "Date", "Folder"],
label="Search Results"
)
with gr.TabItem("πŸ“š API Info"):
gr.Markdown("""
## API Endpoints
### Create Project
```bash
curl -X POST "https://yukee1992-video-project-manager.hf.space/api/create" \\
-H "Content-Type: application/json" \\
-d '{"data": ["Title", "Content", "tags", "prompt", "{}"]}'
```
### Health Check
```bash
curl -X POST "https://yukee1992-video-project-manager.hf.space/api/health" \\
-H "Content-Type: application/json" \\
-d '{}'
```
""")
# Gradio event handlers
create_btn.click(
fn=create_project,
inputs=[title_input, content_input, tags_input, image_input, channel_input],
outputs=[output]
)
search_btn.click(
fn=search_projects,
inputs=[search_input],
outputs=[results]
)
print("βœ… Gradio interface created")
# Mount Gradio app to FastAPI
app = gr.mount_gradio_app(app, demo, path="/")
# =============================================
# RUN
# =============================================
if __name__ == "__main__":
print("\n" + "=" * 60)
print("🌐 Starting server on port 7860...")
print(" - UI: https://yukee1992-video-project-manager.hf.space")
print(" - API: https://yukee1992-video-project-manager.hf.space/api/")
print(" - Endpoints: /api/create, /api/health, /api/search")
print("=" * 60)
uvicorn.run(app, host="0.0.0.0", port=7860)