AntDX316 commited on
Commit
335d8f4
·
1 Parent(s): d6b652b
Files changed (5) hide show
  1. Dockerfile +18 -5
  2. app.py +60 -27
  3. healthcheck.html +23 -0
  4. interface.py +46 -0
  5. 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 port 8080 which is what HF Spaces expects
 
12
  EXPOSE 8080
13
 
14
- # Set environment variables for HF Spaces
15
- ENV PORT=8080
16
  ENV PYTHONUNBUFFERED=1
17
  ENV DOCKER_CONTAINER=true
 
 
 
 
18
 
19
- # Run the Python application
20
- CMD ["python", "app.py"]
 
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
- from urllib.parse import urlparse
 
5
 
6
- # This file is used by Hugging Face Spaces to properly identify the app
7
 
8
- # The port that the app will be served on
9
  PORT = int(os.environ.get("PORT", 8080))
 
 
10
 
11
- # Use the directory containing index.html
12
- web_dir = os.path.dirname(os.path.abspath(__file__))
13
- os.chdir(web_dir)
14
-
15
- # Create a simple HTTP request handler
16
- class SimpleHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
17
- def log_request(self, code='-', size='-'):
18
- # Override to reduce logging noise
19
- if isinstance(code, str):
20
- pass
21
- elif code >= 400:
22
- print(f"HTTP Error {code}: {self.requestline}")
23
- else:
24
- pass # Don't log successful requests
25
-
26
- # Print startup message
27
- print(f"Starting Battle Simulator on port {PORT}")
28
- print(f"Serving from directory: {web_dir}")
29
- print("App can be accessed at the 'App' tab in the Space UI")
30
-
31
- # Start the server
32
- with socketserver.TCPServer(("", PORT), SimpleHTTPRequestHandler) as httpd:
33
- print(f"Serving HTTP on 0.0.0.0 port {PORT}")
34
- httpd.serve_forever()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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