Nagesh Muralidhar commited on
Commit
2251ba3
·
1 Parent(s): 8f0bc94

added static

Browse files
Files changed (3) hide show
  1. Dockerfile +15 -20
  2. app.py +48 -15
  3. static/index.html +256 -0
Dockerfile CHANGED
@@ -16,31 +16,26 @@ RUN apt-get update && \
16
  # Copy the application code
17
  COPY . .
18
 
19
- # Execute the build frontend script to prepare frontend code
20
- RUN chmod +x build_frontend.sh && ./build_frontend.sh
 
 
 
 
 
21
 
22
- # Build frontend
23
- WORKDIR /app/frontend/podcraft
24
- RUN npm install && \
25
- npm run build || \
26
- (echo "Frontend build failed, creating dummy build directory" && \
27
- mkdir -p build && \
28
- echo "<html><head><title>PodCraft</title></head><body><h1>PodCraft</h1><p>Frontend not built correctly. Please check logs.</p></body></html>" > build/index.html)
29
 
30
- # Return to app directory and install backend dependencies
31
- WORKDIR /app
32
- RUN pip install --no-cache-dir -r requirements.txt
33
 
34
- # Create static directory and copy the built frontend
35
- RUN mkdir -p ./static && \
36
- cp -r frontend/podcraft/build/* ./static/ || echo "No frontend build files to copy"
37
 
38
- # Verify the static files were copied
39
  RUN ls -la ./static && \
40
- if [ -f "./static/index.html" ]; then echo "Frontend build found"; else echo "Frontend build not found"; fi
41
-
42
- # Create directories for temp files
43
- RUN mkdir -p temp_audio temp
44
 
45
  # Default environment variables
46
  ENV PORT=7860
 
16
  # Copy the application code
17
  COPY . .
18
 
19
+ # Make sure static directory exists and has the index.html file
20
+ RUN mkdir -p ./static && \
21
+ if [ ! -f "./static/index.html" ]; then \
22
+ echo "WARNING: No index.html found in static directory"; \
23
+ else \
24
+ echo "Found index.html in static directory"; \
25
+ fi
26
 
27
+ # Create directories for temp files
28
+ RUN mkdir -p temp_audio temp
 
 
 
 
 
29
 
30
+ # Execute the build frontend script to prepare frontend code
31
+ RUN chmod +x build_frontend.sh && ./build_frontend.sh || echo "Frontend build script failed but continuing"
 
32
 
33
+ # Install backend dependencies
34
+ RUN pip install --no-cache-dir -r requirements.txt
 
35
 
36
+ # Verify the static files
37
  RUN ls -la ./static && \
38
+ if [ -f "./static/index.html" ]; then echo "Frontend index.html found"; else echo "WARNING: Frontend index.html not found"; fi
 
 
 
39
 
40
  # Default environment variables
41
  ENV PORT=7860
app.py CHANGED
@@ -14,6 +14,33 @@ sys.path.append(os.path.abspath("backend"))
14
  # Create necessary directories if they don't exist
15
  os.makedirs("./temp_audio", exist_ok=True)
16
  os.makedirs("./temp", exist_ok=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  # Set environment variables for MongoDB connection timeout
19
  os.environ["MONGODB_CONNECT_TIMEOUT_MS"] = "5000" # 5 seconds timeout
@@ -21,17 +48,16 @@ os.environ["MONGODB_SERVER_SELECTION_TIMEOUT_MS"] = "5000" # 5 seconds timeout
21
 
22
  # Create a FastAPI app - either the main one or an error one
23
  from fastapi import FastAPI, Request
24
- from fastapi.responses import HTMLResponse, JSONResponse
25
  from fastapi.staticfiles import StaticFiles
26
  from fastapi.middleware.cors import CORSMiddleware
27
 
28
  # Check if static directory exists with index.html
29
- static_path = Path("./static")
30
- static_index_exists = static_path.exists() and (static_path / "index.html").exists()
31
  logger.info(f"Static path exists: {static_path.exists()}")
32
  if static_path.exists():
33
  logger.info(f"Static directory contents: {os.listdir(static_path)}")
34
- logger.info(f"Static index exists: {(static_path / 'index.html').exists()}")
35
 
36
  try:
37
  # Try to import the main app
@@ -54,11 +80,12 @@ try:
54
  # Override the root route to serve the frontend
55
  @app.get("/", response_class=HTMLResponse)
56
  async def read_root():
57
- # If static files exist, return the index.html file
58
- if static_index_exists:
59
- with open(static_path / "index.html") as f:
60
- return f.read()
61
  else:
 
62
  return """
63
  <html>
64
  <head>
@@ -87,10 +114,13 @@ try:
87
  """
88
 
89
  # Mount static files
90
- if static_index_exists:
91
- # Use the mount approach for static assets like CSS/JS, but not for the root path
92
- logger.info("Mounting static files at /static")
93
- app.mount("/static", StaticFiles(directory="./static"), name="static")
 
 
 
94
 
95
  app_to_run = app
96
  logger.info("Using main application")
@@ -129,9 +159,12 @@ except Exception as e:
129
  </html>
130
  """
131
 
132
- # Mount static files if they exist
133
- if static_index_exists:
134
- error_app.mount("/static", StaticFiles(directory="./static"), name="static")
 
 
 
135
 
136
  app_to_run = error_app
137
  logger.info("Using error application")
 
14
  # Create necessary directories if they don't exist
15
  os.makedirs("./temp_audio", exist_ok=True)
16
  os.makedirs("./temp", exist_ok=True)
17
+ os.makedirs("./static", exist_ok=True)
18
+
19
+ # Check for index.html and create a simple one if it doesn't exist
20
+ static_path = Path("./static")
21
+ index_path = static_path / "index.html"
22
+ if not index_path.exists():
23
+ logger.warning("index.html not found in static directory, creating a simple one")
24
+ with open(index_path, "w") as f:
25
+ f.write("""<!DOCTYPE html>
26
+ <html>
27
+ <head>
28
+ <title>PodCraft API</title>
29
+ <style>
30
+ body { font-family: Arial, sans-serif; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f8f9fa; }
31
+ .container { max-width: 800px; padding: 2rem; background-color: white; border-radius: 0.5rem; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); }
32
+ h1 { color: #6366F1; }
33
+ pre { background-color: #f5f5f5; padding: 1rem; border-radius: 0.25rem; overflow: auto; }
34
+ </style>
35
+ </head>
36
+ <body>
37
+ <div class="container">
38
+ <h1>PodCraft API</h1>
39
+ <p>The PodCraft API is running. You can access the API at <a href="/docs">/docs</a>.</p>
40
+ <p>API Status: <a href="/api/status">/api/status</a></p>
41
+ </div>
42
+ </body>
43
+ </html>""")
44
 
45
  # Set environment variables for MongoDB connection timeout
46
  os.environ["MONGODB_CONNECT_TIMEOUT_MS"] = "5000" # 5 seconds timeout
 
48
 
49
  # Create a FastAPI app - either the main one or an error one
50
  from fastapi import FastAPI, Request
51
+ from fastapi.responses import HTMLResponse, JSONResponse, FileResponse
52
  from fastapi.staticfiles import StaticFiles
53
  from fastapi.middleware.cors import CORSMiddleware
54
 
55
  # Check if static directory exists with index.html
56
+ static_index_exists = static_path.exists() and index_path.exists()
 
57
  logger.info(f"Static path exists: {static_path.exists()}")
58
  if static_path.exists():
59
  logger.info(f"Static directory contents: {os.listdir(static_path)}")
60
+ logger.info(f"Static index exists: {index_path.exists()}")
61
 
62
  try:
63
  # Try to import the main app
 
80
  # Override the root route to serve the frontend
81
  @app.get("/", response_class=HTMLResponse)
82
  async def read_root():
83
+ # If index.html exists, return it directly using FileResponse
84
+ if index_path.exists():
85
+ logger.info(f"Serving index.html from {index_path}")
86
+ return FileResponse(index_path)
87
  else:
88
+ logger.warning("index.html not found, returning fallback HTML")
89
  return """
90
  <html>
91
  <head>
 
114
  """
115
 
116
  # Mount static files
117
+ # First, make sure we're not serving the root path via StaticFiles
118
+ @app.get("/static/{path:path}")
119
+ async def serve_static(path: str):
120
+ file_path = static_path / path
121
+ if file_path.exists() and file_path.is_file():
122
+ return FileResponse(file_path)
123
+ return {"error": "File not found"}
124
 
125
  app_to_run = app
126
  logger.info("Using main application")
 
159
  </html>
160
  """
161
 
162
+ @error_app.get("/static/{path:path}")
163
+ async def serve_static(path: str):
164
+ file_path = static_path / path
165
+ if file_path.exists() and file_path.is_file():
166
+ return FileResponse(file_path)
167
+ return {"error": "File not found"}
168
 
169
  app_to_run = error_app
170
  logger.info("Using error application")
static/index.html ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>PodCraft - AI Podcast Generator</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" />
8
+ <style>
9
+ body {
10
+ margin: 0;
11
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
12
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
13
+ -webkit-font-smoothing: antialiased;
14
+ -moz-osx-font-smoothing: grayscale;
15
+ background-color: #1a1a2e;
16
+ color: #ffffff;
17
+ }
18
+
19
+ * {
20
+ box-sizing: border-box;
21
+ }
22
+
23
+ .App {
24
+ text-align: center;
25
+ }
26
+
27
+ .App-header {
28
+ background-color: #0f0f1a;
29
+ min-height: 100vh;
30
+ display: flex;
31
+ flex-direction: column;
32
+ align-items: center;
33
+ justify-content: flex-start;
34
+ padding: 2rem;
35
+ }
36
+
37
+ .logo {
38
+ display: flex;
39
+ align-items: center;
40
+ margin-bottom: 1rem;
41
+ }
42
+
43
+ .logo i {
44
+ font-size: 3rem;
45
+ color: #6366F1;
46
+ margin-right: 1rem;
47
+ }
48
+
49
+ .logo h1 {
50
+ font-size: 3rem;
51
+ margin: 0;
52
+ background: linear-gradient(90deg, #6366F1, #8B5CF6);
53
+ -webkit-background-clip: text;
54
+ -webkit-text-fill-color: transparent;
55
+ }
56
+
57
+ .tagline {
58
+ font-size: 1.5rem;
59
+ margin-bottom: 3rem;
60
+ color: #94a3b8;
61
+ }
62
+
63
+ .status-container {
64
+ width: 100%;
65
+ max-width: 800px;
66
+ margin-bottom: 3rem;
67
+ }
68
+
69
+ .status-card {
70
+ background-color: #1e1e2d;
71
+ border-radius: 0.5rem;
72
+ padding: 1.5rem;
73
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
74
+ }
75
+
76
+ .status-header {
77
+ display: flex;
78
+ align-items: center;
79
+ margin-bottom: 1rem;
80
+ }
81
+
82
+ .status-header i {
83
+ font-size: 1.5rem;
84
+ color: #6366F1;
85
+ margin-right: 0.5rem;
86
+ }
87
+
88
+ .status-header h3 {
89
+ margin: 0;
90
+ font-size: 1.2rem;
91
+ }
92
+
93
+ .status-content {
94
+ display: flex;
95
+ flex-direction: column;
96
+ align-items: center;
97
+ }
98
+
99
+ .status-indicator {
100
+ padding: 0.5rem 1.5rem;
101
+ border-radius: 2rem;
102
+ font-weight: bold;
103
+ margin-bottom: 1rem;
104
+ }
105
+
106
+ .status-indicator.checking {
107
+ background-color: #374151;
108
+ color: #d1d5db;
109
+ }
110
+
111
+ .status-indicator.online {
112
+ background-color: #065f46;
113
+ color: #a7f3d0;
114
+ }
115
+
116
+ .status-indicator.offline {
117
+ background-color: #991b1b;
118
+ color: #fecaca;
119
+ }
120
+
121
+ .status-message {
122
+ font-style: italic;
123
+ color: #94a3b8;
124
+ }
125
+
126
+ .features {
127
+ display: flex;
128
+ flex-wrap: wrap;
129
+ justify-content: center;
130
+ gap: 2rem;
131
+ margin-bottom: 3rem;
132
+ width: 100%;
133
+ max-width: 1000px;
134
+ }
135
+
136
+ .feature {
137
+ background-color: #1e1e2d;
138
+ border-radius: 0.5rem;
139
+ padding: 1.5rem;
140
+ width: 100%;
141
+ max-width: 300px;
142
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
143
+ transition: transform 0.3s ease;
144
+ }
145
+
146
+ .feature:hover {
147
+ transform: translateY(-5px);
148
+ }
149
+
150
+ .feature i {
151
+ font-size: 2.5rem;
152
+ color: #8B5CF6;
153
+ margin-bottom: 1rem;
154
+ }
155
+
156
+ .feature h3 {
157
+ margin: 0;
158
+ margin-bottom: 0.5rem;
159
+ font-size: 1.2rem;
160
+ }
161
+
162
+ .feature p {
163
+ margin: 0;
164
+ color: #94a3b8;
165
+ font-size: 0.9rem;
166
+ }
167
+
168
+ .note {
169
+ margin-top: 2rem;
170
+ padding: 1rem;
171
+ background-color: #1e1e2d;
172
+ border-radius: 0.5rem;
173
+ width: 100%;
174
+ max-width: 800px;
175
+ }
176
+
177
+ .note p {
178
+ margin: 0.5rem 0;
179
+ color: #94a3b8;
180
+ font-size: 0.9rem;
181
+ }
182
+ </style>
183
+ </head>
184
+ <body>
185
+ <div class="App">
186
+ <header class="App-header">
187
+ <div class="logo">
188
+ <i class="fas fa-microphone-alt"></i>
189
+ <h1>PodCraft</h1>
190
+ </div>
191
+ <p class="tagline">AI-Powered Podcast Generator</p>
192
+
193
+ <div class="status-container">
194
+ <div class="status-card">
195
+ <div class="status-header">
196
+ <i class="fas fa-server"></i>
197
+ <h3>API Status</h3>
198
+ </div>
199
+ <div class="status-content">
200
+ <div id="status-indicator" class="status-indicator checking">
201
+ Checking...
202
+ </div>
203
+ <p id="status-message" class="status-message"></p>
204
+ </div>
205
+ </div>
206
+ </div>
207
+
208
+ <div class="features">
209
+ <div class="feature">
210
+ <i class="fas fa-robot"></i>
211
+ <h3>AI Debate</h3>
212
+ <p>Create engaging debates between AI personalities</p>
213
+ </div>
214
+ <div class="feature">
215
+ <i class="fas fa-podcast"></i>
216
+ <h3>Podcast Generation</h3>
217
+ <p>Convert debates into audio podcasts</p>
218
+ </div>
219
+ <div class="feature">
220
+ <i class="fas fa-cogs"></i>
221
+ <h3>Workflow Editor</h3>
222
+ <p>Customize the podcast creation process</p>
223
+ </div>
224
+ </div>
225
+
226
+ <div class="note">
227
+ <p>Note: This is a simplified UI for the application.</p>
228
+ <p>Access the API at <a href="/docs" style="color: #8B5CF6;">/docs</a> for full functionality.</p>
229
+ <p>Check API status at <a href="/api/status" style="color: #8B5CF6;">/api/status</a>.</p>
230
+ </div>
231
+ </header>
232
+ </div>
233
+
234
+ <script>
235
+ // Check API status on load
236
+ document.addEventListener('DOMContentLoaded', function() {
237
+ const statusIndicator = document.getElementById('status-indicator');
238
+ const statusMessage = document.getElementById('status-message');
239
+
240
+ fetch('/api/status')
241
+ .then(response => response.json())
242
+ .then(data => {
243
+ statusIndicator.className = 'status-indicator online';
244
+ statusIndicator.textContent = 'Online';
245
+ statusMessage.textContent = data.message || 'API is running';
246
+ })
247
+ .catch(error => {
248
+ statusIndicator.className = 'status-indicator offline';
249
+ statusIndicator.textContent = 'Offline';
250
+ statusMessage.textContent = 'Could not connect to API';
251
+ console.error('API Error:', error);
252
+ });
253
+ });
254
+ </script>
255
+ </body>
256
+ </html>