AntDX316
commited on
Commit
·
335d8f4
1
Parent(s):
d6b652b
updated
Browse files- Dockerfile +18 -5
- app.py +60 -27
- healthcheck.html +23 -0
- interface.py +46 -0
- requirements.txt +1 -0
Dockerfile
CHANGED
@@ -2,19 +2,32 @@ FROM python:3.10-slim
|
|
2 |
|
3 |
WORKDIR /app
|
4 |
|
|
|
|
|
|
|
|
|
5 |
# Copy application files
|
6 |
COPY index.html /app/
|
7 |
COPY styles.css /app/
|
8 |
COPY script.js /app/
|
9 |
COPY app.py /app/
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
-
# Expose
|
|
|
12 |
EXPOSE 8080
|
13 |
|
14 |
-
# Set environment variables
|
15 |
-
ENV PORT=8080
|
16 |
ENV PYTHONUNBUFFERED=1
|
17 |
ENV DOCKER_CONTAINER=true
|
|
|
|
|
|
|
|
|
18 |
|
19 |
-
# Run the
|
20 |
-
CMD ["python", "
|
|
|
2 |
|
3 |
WORKDIR /app
|
4 |
|
5 |
+
# Copy requirements first for better caching
|
6 |
+
COPY requirements.txt /app/
|
7 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
8 |
+
|
9 |
# Copy application files
|
10 |
COPY index.html /app/
|
11 |
COPY styles.css /app/
|
12 |
COPY script.js /app/
|
13 |
COPY app.py /app/
|
14 |
+
COPY healthcheck.html /app/
|
15 |
+
COPY interface.py /app/
|
16 |
+
|
17 |
+
# Set proper permissions
|
18 |
+
RUN chmod -R 755 /app
|
19 |
|
20 |
+
# Expose ports (Gradio uses 7860 by default)
|
21 |
+
EXPOSE 7860
|
22 |
EXPOSE 8080
|
23 |
|
24 |
+
# Set environment variables
|
|
|
25 |
ENV PYTHONUNBUFFERED=1
|
26 |
ENV DOCKER_CONTAINER=true
|
27 |
+
ENV HF_SPACE=true
|
28 |
+
|
29 |
+
# Print environment for debugging
|
30 |
+
RUN echo "Files in container:" && ls -la /app/
|
31 |
|
32 |
+
# Run the Gradio interface
|
33 |
+
CMD ["python", "-u", "interface.py"]
|
app.py
CHANGED
@@ -1,34 +1,67 @@
|
|
1 |
import os
|
2 |
import http.server
|
3 |
import socketserver
|
4 |
-
|
|
|
5 |
|
6 |
-
# This file is
|
7 |
|
8 |
-
#
|
9 |
PORT = int(os.environ.get("PORT", 8080))
|
|
|
|
|
10 |
|
11 |
-
#
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
#
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import os
|
2 |
import http.server
|
3 |
import socketserver
|
4 |
+
import threading
|
5 |
+
import time
|
6 |
|
7 |
+
# This file is for serving our static app on Hugging Face Spaces
|
8 |
|
9 |
+
# Configuration
|
10 |
PORT = int(os.environ.get("PORT", 8080))
|
11 |
+
HOST = "0.0.0.0" # Listen on all interfaces
|
12 |
+
DIRECTORY = os.path.dirname(os.path.abspath(__file__))
|
13 |
|
14 |
+
# Change to the directory with our static files
|
15 |
+
os.chdir(DIRECTORY)
|
16 |
+
|
17 |
+
# Custom request handler with better error handling
|
18 |
+
class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
|
19 |
+
# Set correct MIME types
|
20 |
+
extensions_map = {
|
21 |
+
'.html': 'text/html',
|
22 |
+
'.css': 'text/css',
|
23 |
+
'.js': 'application/javascript',
|
24 |
+
'.json': 'application/json',
|
25 |
+
'.png': 'image/png',
|
26 |
+
'.jpg': 'image/jpeg',
|
27 |
+
'.jpeg': 'image/jpeg',
|
28 |
+
'.gif': 'image/gif',
|
29 |
+
'.svg': 'image/svg+xml',
|
30 |
+
'': 'application/octet-stream',
|
31 |
+
}
|
32 |
+
|
33 |
+
def log_message(self, format, *args):
|
34 |
+
# Enhanced logging
|
35 |
+
print(f"[{self.log_date_time_string()}] {format % args}")
|
36 |
+
|
37 |
+
def do_GET(self):
|
38 |
+
# Handle specific paths
|
39 |
+
if self.path == '/' or self.path == '':
|
40 |
+
self.path = '/index.html'
|
41 |
+
|
42 |
+
# Print detailed request info for debugging
|
43 |
+
print(f"Handling request for: {self.path}")
|
44 |
+
|
45 |
+
# Serve the file
|
46 |
+
return http.server.SimpleHTTPRequestHandler.do_GET(self)
|
47 |
+
|
48 |
+
# Print startup information
|
49 |
+
print("=" * 60)
|
50 |
+
print(f"Starting Battle Simulator Server")
|
51 |
+
print(f"Current directory: {DIRECTORY}")
|
52 |
+
print(f"Files in directory:")
|
53 |
+
for file in os.listdir(DIRECTORY):
|
54 |
+
print(f" - {file}")
|
55 |
+
print(f"Listening on {HOST}:{PORT}")
|
56 |
+
print("=" * 60)
|
57 |
+
|
58 |
+
# Create and start the server
|
59 |
+
handler = CustomHTTPRequestHandler
|
60 |
+
httpd = socketserver.TCPServer((HOST, PORT), handler)
|
61 |
+
|
62 |
+
# Print ready message
|
63 |
+
print(f"Server started - Battle Simulator ready!")
|
64 |
+
print(f"Open the 'App' tab to view the application")
|
65 |
+
|
66 |
+
# Start serving
|
67 |
+
httpd.serve_forever()
|
healthcheck.html
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>Battle Simulator Health Check</title>
|
5 |
+
<meta charset="UTF-8">
|
6 |
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
7 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
8 |
+
<!-- Special meta tags for Hugging Face Spaces -->
|
9 |
+
<meta property="og:title" content="Battle Simulator">
|
10 |
+
<meta property="og:description" content="Interactive battle simulation with units on a map">
|
11 |
+
</head>
|
12 |
+
<body>
|
13 |
+
<h1>Battle Simulator is running!</h1>
|
14 |
+
<p>Status: OK</p>
|
15 |
+
<p>If you're seeing this page directly, please click on the "App" tab to view the simulation.</p>
|
16 |
+
<script>
|
17 |
+
// Redirect to index.html if accessed directly
|
18 |
+
if (window.location.pathname === '/healthcheck.html') {
|
19 |
+
window.location.href = '/';
|
20 |
+
}
|
21 |
+
</script>
|
22 |
+
</body>
|
23 |
+
</html>
|
interface.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import os
|
3 |
+
import http.server
|
4 |
+
import socketserver
|
5 |
+
import threading
|
6 |
+
import webbrowser
|
7 |
+
|
8 |
+
# Define constants
|
9 |
+
PORT = int(os.environ.get("PORT", 8080))
|
10 |
+
HOST = "0.0.0.0" # Listen on all interfaces
|
11 |
+
DIRECTORY = os.path.dirname(os.path.abspath(__file__))
|
12 |
+
|
13 |
+
# Start HTTP server in a separate thread
|
14 |
+
def start_http_server():
|
15 |
+
os.chdir(DIRECTORY)
|
16 |
+
handler = http.server.SimpleHTTPRequestHandler
|
17 |
+
httpd = socketserver.TCPServer((HOST, PORT), handler)
|
18 |
+
print(f"Server started at http://{HOST}:{PORT}")
|
19 |
+
print(f"Current directory: {DIRECTORY}")
|
20 |
+
httpd.serve_forever()
|
21 |
+
|
22 |
+
# Start server in a background thread
|
23 |
+
server_thread = threading.Thread(target=start_http_server, daemon=True)
|
24 |
+
server_thread.start()
|
25 |
+
|
26 |
+
# Create a simple Gradio interface for Hugging Face
|
27 |
+
with gr.Blocks() as demo:
|
28 |
+
gr.HTML(f"""
|
29 |
+
<iframe
|
30 |
+
src="http://{HOST}:{PORT}"
|
31 |
+
width="100%"
|
32 |
+
height="800px"
|
33 |
+
frameborder="0"
|
34 |
+
style="border: 1px solid #ddd; border-radius: 8px;"
|
35 |
+
></iframe>
|
36 |
+
<div style="text-align: center; margin-top: 10px; padding: 10px; background-color: #f8f8f8; border-radius: 5px;">
|
37 |
+
<h3>Battle Simulator</h3>
|
38 |
+
<p>If the simulation doesn't appear above, you can access it directly at:
|
39 |
+
<a href="http://{HOST}:{PORT}" target="_blank">Battle Simulator</a>
|
40 |
+
</p>
|
41 |
+
</div>
|
42 |
+
""")
|
43 |
+
|
44 |
+
# Launch the interface
|
45 |
+
if __name__ == "__main__":
|
46 |
+
demo.launch(server_name=HOST, server_port=7860)
|
requirements.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
gradio>=3.50.2
|