Spaces:
Sleeping
Sleeping
Nagesh Muralidhar
commited on
Commit
·
0d27572
1
Parent(s):
fd52f31
Initial commit of PodCraft application
Browse files- .gitattributes +6 -0
- .gitignore +83 -13
- Dockerfile +10 -0
- Dockerfile.spaces +11 -1
- app/main.py +69 -30
- push_to_huggingface.sh +46 -0
- space.yml +1 -0
.gitattributes
CHANGED
@@ -39,3 +39,9 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
39 |
*.png filter=lfs diff=lfs merge=lfs -text
|
40 |
*.jpg filter=lfs diff=lfs merge=lfs -text
|
41 |
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
*.png filter=lfs diff=lfs merge=lfs -text
|
40 |
*.jpg filter=lfs diff=lfs merge=lfs -text
|
41 |
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
42 |
+
*.wav filter=lfs diff=lfs merge=lfs -text
|
43 |
+
*.ogg filter=lfs diff=lfs merge=lfs -text
|
44 |
+
*.woff filter=lfs diff=lfs merge=lfs -text
|
45 |
+
*.woff2 filter=lfs diff=lfs merge=lfs -text
|
46 |
+
*.ttf filter=lfs diff=lfs merge=lfs -text
|
47 |
+
*.otf filter=lfs diff=lfs merge=lfs -text
|
.gitignore
CHANGED
@@ -1,14 +1,84 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
.DS_Store
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Node.js dependencies
|
2 |
+
node_modules/
|
3 |
+
npm-debug.log
|
4 |
+
yarn-error.log
|
5 |
+
package-lock.json
|
6 |
+
yarn.lock
|
7 |
+
|
8 |
+
# Python cache files
|
9 |
+
__pycache__/
|
10 |
+
*.py[cod]
|
11 |
+
*$py.class
|
12 |
+
*.so
|
13 |
+
.Python
|
14 |
+
env/
|
15 |
+
build/
|
16 |
+
develop-eggs/
|
17 |
+
dist/
|
18 |
+
downloads/
|
19 |
+
eggs/
|
20 |
+
.eggs/
|
21 |
+
lib/
|
22 |
+
lib64/
|
23 |
+
parts/
|
24 |
+
sdist/
|
25 |
+
var/
|
26 |
+
*.egg-info/
|
27 |
+
.installed.cfg
|
28 |
+
*.egg
|
29 |
+
|
30 |
+
# Virtual Environment
|
31 |
+
venv/
|
32 |
+
ENV/
|
33 |
+
env/
|
34 |
+
|
35 |
+
# Editor directories and files
|
36 |
+
.idea/
|
37 |
+
.vscode/
|
38 |
+
*.swp
|
39 |
+
*.swo
|
40 |
.DS_Store
|
41 |
+
|
42 |
+
# Environment variables
|
43 |
+
.env
|
44 |
+
.env.local
|
45 |
+
.env.development.local
|
46 |
+
.env.test.local
|
47 |
+
.env.production.local
|
48 |
+
|
49 |
+
# Audio files
|
50 |
+
temp_audio/
|
51 |
+
*.mp3
|
52 |
+
*.wav
|
53 |
+
*.ogg
|
54 |
+
|
55 |
+
# Logs
|
56 |
+
logs/
|
57 |
+
*.log
|
58 |
+
npm-debug.log*
|
59 |
+
yarn-debug.log*
|
60 |
+
yarn-error.log*
|
61 |
+
|
62 |
+
# Distribution / packaging
|
63 |
+
.Python
|
64 |
+
build/
|
65 |
+
develop-eggs/
|
66 |
+
dist/
|
67 |
+
downloads/
|
68 |
+
eggs/
|
69 |
+
.eggs/
|
70 |
+
lib/
|
71 |
+
lib64/
|
72 |
+
parts/
|
73 |
+
sdist/
|
74 |
+
var/
|
75 |
+
wheels/
|
76 |
+
*.egg-info/
|
77 |
+
.installed.cfg
|
78 |
+
*.egg
|
79 |
+
|
80 |
+
# Jupyter Notebook
|
81 |
+
.ipynb_checkpoints
|
82 |
+
|
83 |
+
# Docker
|
84 |
+
.dockerignore
|
Dockerfile
CHANGED
@@ -7,6 +7,8 @@ RUN apt-get update && \
|
|
7 |
apt-get install -y --no-install-recommends \
|
8 |
ffmpeg \
|
9 |
build-essential \
|
|
|
|
|
10 |
&& rm -rf /var/lib/apt/lists/*
|
11 |
|
12 |
# Copy requirements first to leverage Docker cache
|
@@ -16,6 +18,9 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|
16 |
# Copy backend code
|
17 |
COPY backend/app/ /app/app/
|
18 |
|
|
|
|
|
|
|
19 |
# Copy frontend build to static directory
|
20 |
COPY frontend/podcraft/build/ /app/static/
|
21 |
|
@@ -29,6 +34,11 @@ RUN mkdir -p /app/temp_audio
|
|
29 |
ENV PYTHONPATH=/app
|
30 |
ENV MONGODB_URL="mongodb+srv://NageshBM:Nash166^@podcraft.ozqmc.mongodb.net/?retryWrites=true&w=majority&appName=Podcraft"
|
31 |
|
|
|
|
|
|
|
|
|
|
|
32 |
# Expose the port the app runs on
|
33 |
EXPOSE 8000
|
34 |
|
|
|
7 |
apt-get install -y --no-install-recommends \
|
8 |
ffmpeg \
|
9 |
build-essential \
|
10 |
+
curl \
|
11 |
+
gnupg \
|
12 |
&& rm -rf /var/lib/apt/lists/*
|
13 |
|
14 |
# Copy requirements first to leverage Docker cache
|
|
|
18 |
# Copy backend code
|
19 |
COPY backend/app/ /app/app/
|
20 |
|
21 |
+
# Ensure static directory exists
|
22 |
+
RUN mkdir -p /app/static
|
23 |
+
|
24 |
# Copy frontend build to static directory
|
25 |
COPY frontend/podcraft/build/ /app/static/
|
26 |
|
|
|
34 |
ENV PYTHONPATH=/app
|
35 |
ENV MONGODB_URL="mongodb+srv://NageshBM:Nash166^@podcraft.ozqmc.mongodb.net/?retryWrites=true&w=majority&appName=Podcraft"
|
36 |
|
37 |
+
# Copy the placeholder index.html if the app/static directory is empty
|
38 |
+
RUN if [ -z "$(ls -A /app/static 2>/dev/null)" ]; then \
|
39 |
+
echo "<html><body><h1>PodCraft API</h1><p>Frontend not available. Please build the frontend before running.</p></body></html>" > /app/static/index.html; \
|
40 |
+
fi
|
41 |
+
|
42 |
# Expose the port the app runs on
|
43 |
EXPOSE 8000
|
44 |
|
Dockerfile.spaces
CHANGED
@@ -7,6 +7,8 @@ RUN apt-get update && \
|
|
7 |
apt-get install -y --no-install-recommends \
|
8 |
ffmpeg \
|
9 |
build-essential \
|
|
|
|
|
10 |
&& rm -rf /var/lib/apt/lists/*
|
11 |
|
12 |
# Copy requirements first to leverage Docker cache
|
@@ -14,7 +16,10 @@ COPY backend/requirements.txt .
|
|
14 |
RUN pip install --no-cache-dir -r requirements.txt
|
15 |
|
16 |
# Copy backend code
|
17 |
-
COPY backend/app /app/app/
|
|
|
|
|
|
|
18 |
|
19 |
# Copy frontend build to static directory if available
|
20 |
COPY frontend/podcraft/build/ /app/static/
|
@@ -32,6 +37,11 @@ ENV PYTHONPATH=/app
|
|
32 |
# MongoDB_URL is hardcoded to the Atlas URL in this case
|
33 |
ENV MONGODB_URL="mongodb+srv://NageshBM:Nash166^@podcraft.ozqmc.mongodb.net/?retryWrites=true&w=majority&appName=Podcraft"
|
34 |
|
|
|
|
|
|
|
|
|
|
|
35 |
# Expose the port the app runs on
|
36 |
EXPOSE 7860
|
37 |
|
|
|
7 |
apt-get install -y --no-install-recommends \
|
8 |
ffmpeg \
|
9 |
build-essential \
|
10 |
+
curl \
|
11 |
+
gnupg \
|
12 |
&& rm -rf /var/lib/apt/lists/*
|
13 |
|
14 |
# Copy requirements first to leverage Docker cache
|
|
|
16 |
RUN pip install --no-cache-dir -r requirements.txt
|
17 |
|
18 |
# Copy backend code
|
19 |
+
COPY backend/app/ /app/app/
|
20 |
+
|
21 |
+
# Ensure static directory exists
|
22 |
+
RUN mkdir -p /app/static
|
23 |
|
24 |
# Copy frontend build to static directory if available
|
25 |
COPY frontend/podcraft/build/ /app/static/
|
|
|
37 |
# MongoDB_URL is hardcoded to the Atlas URL in this case
|
38 |
ENV MONGODB_URL="mongodb+srv://NageshBM:Nash166^@podcraft.ozqmc.mongodb.net/?retryWrites=true&w=majority&appName=Podcraft"
|
39 |
|
40 |
+
# Copy the placeholder index.html if the app/static directory is empty
|
41 |
+
RUN if [ -z "$(ls -A /app/static 2>/dev/null)" ]; then \
|
42 |
+
echo "<html><body><h1>PodCraft API</h1><p>Frontend not available. Please build the frontend before running.</p></body></html>" > /app/static/index.html; \
|
43 |
+
fi
|
44 |
+
|
45 |
# Expose the port the app runs on
|
46 |
EXPOSE 7860
|
47 |
|
app/main.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
from fastapi import FastAPI, Request, HTTPException, Depends, status, File, UploadFile, Form
|
2 |
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
3 |
-
from fastapi.responses import JSONResponse, FileResponse, HTMLResponse
|
4 |
from fastapi.staticfiles import StaticFiles
|
5 |
from fastapi.middleware.cors import CORSMiddleware
|
6 |
from pydantic import BaseModel
|
@@ -114,39 +114,12 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
|
|
114 |
|
115 |
return user
|
116 |
|
117 |
-
# Include all the API routes from the original main.py here
|
118 |
-
# ...
|
119 |
-
|
120 |
-
# Mount static files for frontend
|
121 |
-
static_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "static"))
|
122 |
-
app.mount("/static", StaticFiles(directory=static_path), name="static")
|
123 |
-
|
124 |
-
# Add route to serve the frontend
|
125 |
-
@app.get("/", response_class=HTMLResponse)
|
126 |
-
async def serve_frontend():
|
127 |
-
html_file = os.path.join(static_path, "index.html")
|
128 |
-
if os.path.exists(html_file):
|
129 |
-
with open(html_file, "r") as f:
|
130 |
-
return f.read()
|
131 |
-
else:
|
132 |
-
return HTMLResponse(content="<html><body><h1>PodCraft API</h1><p>Frontend not found.</p></body></html>")
|
133 |
-
|
134 |
-
# Add route to serve audio files
|
135 |
-
@app.get("/audio/{path:path}")
|
136 |
-
async def serve_audio(path: str):
|
137 |
-
audio_file = os.path.join("/app/temp_audio", path)
|
138 |
-
if os.path.exists(audio_file):
|
139 |
-
return FileResponse(audio_file)
|
140 |
-
else:
|
141 |
-
raise HTTPException(status_code=404, detail="Audio file not found")
|
142 |
-
|
143 |
# Route for health check
|
144 |
@app.get("/health")
|
145 |
async def health():
|
146 |
-
return {"status": "healthy"}
|
147 |
-
|
148 |
-
# Include all the original API routes here from the original main.py
|
149 |
|
|
|
150 |
@app.post("/signup")
|
151 |
async def signup(user: UserCreate):
|
152 |
# Check if username exists
|
@@ -194,6 +167,72 @@ async def login(request: Request, user: UserLogin):
|
|
194 |
# Add all the other API routes from the original main.py
|
195 |
# ...
|
196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
if __name__ == "__main__":
|
198 |
import uvicorn
|
199 |
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
|
|
1 |
from fastapi import FastAPI, Request, HTTPException, Depends, status, File, UploadFile, Form
|
2 |
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
3 |
+
from fastapi.responses import JSONResponse, FileResponse, HTMLResponse, RedirectResponse
|
4 |
from fastapi.staticfiles import StaticFiles
|
5 |
from fastapi.middleware.cors import CORSMiddleware
|
6 |
from pydantic import BaseModel
|
|
|
114 |
|
115 |
return user
|
116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
# Route for health check
|
118 |
@app.get("/health")
|
119 |
async def health():
|
120 |
+
return {"status": "healthy", "version": "1.0.0"}
|
|
|
|
|
121 |
|
122 |
+
# API routes
|
123 |
@app.post("/signup")
|
124 |
async def signup(user: UserCreate):
|
125 |
# Check if username exists
|
|
|
167 |
# Add all the other API routes from the original main.py
|
168 |
# ...
|
169 |
|
170 |
+
# Determine static files path
|
171 |
+
static_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "static"))
|
172 |
+
if not os.path.exists(static_path):
|
173 |
+
try:
|
174 |
+
os.makedirs(static_path, exist_ok=True)
|
175 |
+
with open(os.path.join(static_path, "index.html"), "w") as f:
|
176 |
+
f.write("<html><body><h1>PodCraft API</h1><p>Frontend not found.</p></body></html>")
|
177 |
+
except Exception as e:
|
178 |
+
logger.error(f"Error creating static path: {e}")
|
179 |
+
|
180 |
+
# Mount static files for frontend
|
181 |
+
app.mount("/static", StaticFiles(directory=static_path), name="static")
|
182 |
+
|
183 |
+
# Add route to serve audio files
|
184 |
+
@app.get("/audio/{path:path}")
|
185 |
+
async def serve_audio(path: str):
|
186 |
+
audio_dir = "/app/temp_audio"
|
187 |
+
if not os.path.exists(audio_dir):
|
188 |
+
try:
|
189 |
+
os.makedirs(audio_dir, exist_ok=True)
|
190 |
+
except Exception as e:
|
191 |
+
logger.error(f"Error creating audio directory: {e}")
|
192 |
+
|
193 |
+
audio_file = os.path.join(audio_dir, path)
|
194 |
+
if os.path.exists(audio_file):
|
195 |
+
return FileResponse(audio_file)
|
196 |
+
else:
|
197 |
+
raise HTTPException(status_code=404, detail="Audio file not found")
|
198 |
+
|
199 |
+
# Root path to serve frontend or redirect to static
|
200 |
+
@app.get("/", response_class=HTMLResponse)
|
201 |
+
async def serve_frontend():
|
202 |
+
index_file = os.path.join(static_path, "index.html")
|
203 |
+
if os.path.exists(index_file):
|
204 |
+
with open(index_file, "r") as f:
|
205 |
+
return HTMLResponse(content=f.read())
|
206 |
+
else:
|
207 |
+
# Create a minimal index.html if it doesn't exist
|
208 |
+
html_content = """
|
209 |
+
<!DOCTYPE html>
|
210 |
+
<html>
|
211 |
+
<head>
|
212 |
+
<title>PodCraft API</title>
|
213 |
+
<style>
|
214 |
+
body { font-family: Arial, sans-serif; padding: 20px; }
|
215 |
+
h1 { color: #8b5cf6; }
|
216 |
+
</style>
|
217 |
+
</head>
|
218 |
+
<body>
|
219 |
+
<h1>PodCraft API</h1>
|
220 |
+
<p>The frontend application is not available. Please build the frontend or check the documentation.</p>
|
221 |
+
</body>
|
222 |
+
</html>
|
223 |
+
"""
|
224 |
+
return HTMLResponse(content=html_content)
|
225 |
+
|
226 |
+
# Catch-all route for SPA routing - all non-API routes should serve the frontend
|
227 |
+
@app.get("/{full_path:path}")
|
228 |
+
async def catch_all(full_path: str):
|
229 |
+
# If path starts with "api", it's an API route not found
|
230 |
+
if full_path.startswith("api/"):
|
231 |
+
raise HTTPException(status_code=404, detail="API endpoint not found")
|
232 |
+
|
233 |
+
# Otherwise serve the SPA
|
234 |
+
return await serve_frontend()
|
235 |
+
|
236 |
if __name__ == "__main__":
|
237 |
import uvicorn
|
238 |
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
push_to_huggingface.sh
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/bin/bash
|
2 |
+
set -e
|
3 |
+
|
4 |
+
echo "===> Preparing PodCraft for HuggingFace Spaces <===="
|
5 |
+
|
6 |
+
# Check if repository is initialized
|
7 |
+
if [ ! -d ".git" ]; then
|
8 |
+
echo "Initializing git repository..."
|
9 |
+
git init
|
10 |
+
fi
|
11 |
+
|
12 |
+
# Set up Git LFS
|
13 |
+
echo "Setting up Git LFS..."
|
14 |
+
git lfs install
|
15 |
+
git lfs track "*.gif" "*.png" "*.jpg" "*.jpeg" "*.mp3" "*.mp4" "*.wav" "*.ogg"
|
16 |
+
git add .gitattributes
|
17 |
+
|
18 |
+
# Configure git if needed
|
19 |
+
if ! git remote | grep -q "origin"; then
|
20 |
+
echo "Please enter your HuggingFace username:"
|
21 |
+
read username
|
22 |
+
git remote add origin "https://huggingface.co/spaces/$username/podcraft"
|
23 |
+
echo "Remote added: https://huggingface.co/spaces/$username/podcraft"
|
24 |
+
fi
|
25 |
+
|
26 |
+
# Check for large files
|
27 |
+
echo "Checking for large files (>100MB)..."
|
28 |
+
find . -type f -size +100M | while read file; do
|
29 |
+
echo "Warning: Large file detected: $file"
|
30 |
+
echo "Consider removing or excluding it from git."
|
31 |
+
done
|
32 |
+
|
33 |
+
# Prepare for commit
|
34 |
+
echo "Adding files to git..."
|
35 |
+
git add .
|
36 |
+
|
37 |
+
# Commit changes
|
38 |
+
echo "Committing changes..."
|
39 |
+
git commit -m "Update PodCraft for HuggingFace Spaces"
|
40 |
+
|
41 |
+
# Push to HuggingFace
|
42 |
+
echo "Pushing to HuggingFace Spaces..."
|
43 |
+
echo "This may take a while depending on the size of your repository."
|
44 |
+
git push -u origin main
|
45 |
+
|
46 |
+
echo "Push completed! Check your HuggingFace Space for build progress."
|
space.yml
CHANGED
@@ -4,5 +4,6 @@ colorFrom: indigo
|
|
4 |
colorTo: purple
|
5 |
sdk: docker
|
6 |
app_port: 7860
|
|
|
7 |
pinned: false
|
8 |
license: mit
|
|
|
4 |
colorTo: purple
|
5 |
sdk: docker
|
6 |
app_port: 7860
|
7 |
+
dockerfile: Dockerfile.spaces
|
8 |
pinned: false
|
9 |
license: mit
|