anushadudi commited on
Commit
dd67cc7
ยท
verified ยท
1 Parent(s): e161009

Upload folder using huggingface_hub

Browse files
Dockerfile CHANGED
@@ -5,11 +5,12 @@ FROM python:3.11-slim
5
  WORKDIR /app
6
 
7
  # Install requirements
8
- RUN pip install --no-cache-dir fastapi>=0.104.0 uvicorn>=0.24.0 pydantic>=2.0.0 requests>=2.25.0
9
 
10
- # Copy the standalone app
11
  # When deployed to HF, the Dockerfile is moved to root, so server/ contains the app
12
  COPY server/standalone_app.py /app/standalone_app.py
 
13
 
14
  # Expose port 8000
15
  EXPOSE 8000
 
5
  WORKDIR /app
6
 
7
  # Install requirements
8
+ RUN pip install --no-cache-dir fastapi>=0.104.0 uvicorn>=0.24.0 pydantic>=2.0.0 requests>=2.25.0 gradio>=4.0.0
9
 
10
+ # Copy the standalone app and Gradio UI
11
  # When deployed to HF, the Dockerfile is moved to root, so server/ contains the app
12
  COPY server/standalone_app.py /app/standalone_app.py
13
+ COPY server/gradio_ui.py /app/gradio_ui.py
14
 
15
  # Expose port 8000
16
  EXPOSE 8000
server/gradio_ui.py ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Gradio Web Interface for Number Guessing Game Environment
3
+
4
+ This module provides an interactive web UI for the number guessing game
5
+ that can be accessed at the /web endpoint when deployed.
6
+ """
7
+
8
+ import gradio as gr
9
+ from typing import Tuple, List
10
+ import random
11
+
12
+ # Import the environment
13
+ from standalone_app import NumberGuessEnvironment, GuessAction
14
+
15
+ # Global environment instance for the web UI
16
+ web_env = NumberGuessEnvironment()
17
+
18
+
19
+ def reset_game() -> Tuple[str, str, str, str, str, List]:
20
+ """Reset the game and return initial UI state"""
21
+ obs = web_env.reset()
22
+
23
+ welcome_msg = f"""
24
+ # ๐ŸŽฏ Number Guessing Game
25
+
26
+ **{obs.hint}**
27
+
28
+ I'm thinking of a number between 1 and 100.
29
+ Can you guess it in {obs.attempts_remaining} attempts or less?
30
+
31
+ Strategy tip: Try binary search for optimal performance! ๐Ÿง 
32
+ """
33
+
34
+ status = f"๐ŸŽฎ **Game Status:** New Game Started!"
35
+ attempts = f"๐Ÿ“Š **Attempts Remaining:** {obs.attempts_remaining}"
36
+ reward_display = f"๐ŸŽ **Current Reward:** {obs.reward}"
37
+ hint_display = "๐Ÿ’ก **Last Hint:** None yet - Make your first guess!"
38
+ history = []
39
+
40
+ return welcome_msg, status, attempts, reward_display, hint_display, history
41
+
42
+
43
+ def make_guess(guess_input: str, history: List) -> Tuple[str, str, str, str, str, List, str]:
44
+ """Process a guess and return updated UI state"""
45
+
46
+ # Validate input
47
+ if not guess_input or not guess_input.strip():
48
+ return (
49
+ None,
50
+ "โš ๏ธ **Status:** Please enter a number!",
51
+ None, None, None, history, ""
52
+ )
53
+
54
+ try:
55
+ guess = int(guess_input.strip())
56
+ except ValueError:
57
+ return (
58
+ None,
59
+ "โš ๏ธ **Status:** Invalid input! Please enter a number between 1 and 100.",
60
+ None, None, None, history, ""
61
+ )
62
+
63
+ # Make the guess
64
+ action = GuessAction(guess=guess)
65
+ obs = web_env.step(action)
66
+
67
+ # Update history
68
+ history = history or []
69
+ history.append({
70
+ "Guess #": len(history) + 1,
71
+ "Your Guess": guess,
72
+ "Hint": obs.hint,
73
+ "Reward": f"{obs.reward:+.1f}"
74
+ })
75
+
76
+ # Format status message
77
+ if obs.hint == "correct":
78
+ status = f"๐ŸŽ‰ **Congratulations!** You found the number {guess} in {len(history)} attempts!"
79
+ hint_display = "โœจ **Last Hint:** ๐ŸŽฏ CORRECT! You won!"
80
+ elif obs.hint == "game over":
81
+ secret = obs.metadata.get('secret_number', '?')
82
+ status = f"๐Ÿ˜ข **Game Over!** The number was {secret}. Try again!"
83
+ hint_display = f"โŒ **Last Hint:** Out of attempts. The answer was {secret}."
84
+ elif obs.hint.startswith("invalid"):
85
+ status = "โš ๏ธ **Invalid Guess!** Number must be between 1 and 100."
86
+ hint_display = f"โš ๏ธ **Last Hint:** {obs.hint}"
87
+ elif obs.hint == "higher":
88
+ status = f"๐Ÿ“ˆ The number is **HIGHER** than {guess}"
89
+ hint_display = f"โฌ†๏ธ **Last Hint:** Go HIGHER than {guess}"
90
+ elif obs.hint == "lower":
91
+ status = f"๐Ÿ“‰ The number is **LOWER** than {guess}"
92
+ hint_display = f"โฌ‡๏ธ **Last Hint:** Go LOWER than {guess}"
93
+ else:
94
+ status = f"๐Ÿค” Hint: {obs.hint}"
95
+ hint_display = f"๐Ÿ’ก **Last Hint:** {obs.hint}"
96
+
97
+ # Update other displays
98
+ attempts = f"๐Ÿ“Š **Attempts Remaining:** {obs.attempts_remaining}"
99
+ reward_display = f"๐ŸŽ **Total Reward:** {sum(float(h['Reward']) for h in history):.1f}"
100
+
101
+ # Additional context
102
+ welcome_msg = None # Don't update welcome
103
+
104
+ # Clear input for next guess
105
+ next_input = ""
106
+
107
+ return welcome_msg, status, attempts, reward_display, hint_display, history, next_input
108
+
109
+
110
+ def create_gradio_interface() -> gr.Blocks:
111
+ """Create the Gradio interface"""
112
+
113
+ with gr.Blocks(theme=gr.themes.Soft(), title="๐ŸŽฏ Number Guessing Game") as demo:
114
+
115
+ gr.Markdown(
116
+ """
117
+ # ๐ŸŽฏ Number Guessing Game Environment
118
+
119
+ Welcome to the **OpenEnv Number Guessing Game**! Test your reasoning skills by guessing
120
+ a secret number between 1 and 100. You'll get hints after each guess to help you narrow
121
+ down the answer.
122
+
123
+ **Perfect for:**
124
+ - ๐Ÿค– Training RL agents with binary search strategies
125
+ - ๐Ÿง  Testing reasoning and planning algorithms
126
+ - ๐Ÿ“š Learning reinforcement learning concepts
127
+ - ๐ŸŽฎ Having fun!
128
+ """
129
+ )
130
+
131
+ with gr.Row():
132
+ with gr.Column(scale=2):
133
+ # Welcome and instructions
134
+ welcome = gr.Markdown(value=reset_game()[0])
135
+
136
+ # Input area
137
+ with gr.Row():
138
+ guess_input = gr.Textbox(
139
+ label="Your Guess",
140
+ placeholder="Enter a number between 1 and 100...",
141
+ scale=3
142
+ )
143
+ guess_btn = gr.Button("๐ŸŽฏ Guess", variant="primary", scale=1)
144
+
145
+ # Action buttons
146
+ with gr.Row():
147
+ reset_btn = gr.Button("๐Ÿ”„ New Game", variant="secondary")
148
+
149
+ # Status displays
150
+ status = gr.Markdown(value="๐ŸŽฎ **Game Status:** Ready to start!")
151
+ hint_display = gr.Markdown(value="๐Ÿ’ก **Last Hint:** None yet")
152
+
153
+ with gr.Row():
154
+ attempts = gr.Markdown(value="๐Ÿ“Š **Attempts Remaining:** 10")
155
+ reward_display = gr.Markdown(value="๐ŸŽ **Current Reward:** 0.0")
156
+
157
+ with gr.Column(scale=1):
158
+ gr.Markdown("### ๐Ÿ“Š Statistics")
159
+
160
+ # Guess history table
161
+ history_table = gr.Dataframe(
162
+ headers=["Guess #", "Your Guess", "Hint", "Reward"],
163
+ datatype=["number", "number", "str", "str"],
164
+ label="Guess History",
165
+ interactive=False,
166
+ height=400
167
+ )
168
+
169
+ # Tips section
170
+ with gr.Accordion("๐Ÿ’ก Strategy Tips", open=False):
171
+ gr.Markdown(
172
+ """
173
+ ### Optimal Strategy: Binary Search
174
+
175
+ 1. **Start at 50** (middle of 1-100)
176
+ 2. **If "higher":** Search in range [51, 100]
177
+ 3. **If "lower":** Search in range [1, 49]
178
+ 4. **Repeat:** Always guess the middle of your current range
179
+
180
+ This guarantees finding the number in **at most 7 guesses**! ๐ŸŽฏ
181
+
182
+ ### Reward System
183
+ - โœ… **+10.0** - Correct guess (win!)
184
+ - โž• **+0.1** - Valid guess (narrowing down)
185
+ - โŒ **-1.0** - Invalid guess (out of bounds)
186
+ - ๐Ÿ’” **-5.0** - Failed to guess in time
187
+ """
188
+ )
189
+
190
+ # API Information
191
+ with gr.Accordion("๐Ÿ”Œ API Access", open=False):
192
+ gr.Markdown(
193
+ """
194
+ ### Use this environment in your code:
195
+
196
+ ```python
197
+ from envs.number_guess_env import NumberGuessEnv, GuessAction
198
+
199
+ # Connect to this deployed space
200
+ env = NumberGuessEnv(base_url="https://YOUR-SPACE-URL.hf.space")
201
+
202
+ # Play the game
203
+ result = env.reset()
204
+ result = env.step(GuessAction(guess=50))
205
+ print(result.observation.hint)
206
+ ```
207
+
208
+ ### API Endpoints:
209
+ - `POST /reset` - Start new game
210
+ - `POST /step` - Make a guess
211
+ - `GET /state` - Get current state
212
+ - `GET /health` - Health check
213
+ """
214
+ )
215
+
216
+ # Event handlers
217
+ guess_btn.click(
218
+ fn=make_guess,
219
+ inputs=[guess_input, history_table],
220
+ outputs=[welcome, status, attempts, reward_display, hint_display, history_table, guess_input]
221
+ )
222
+
223
+ # Allow Enter key to submit guess
224
+ guess_input.submit(
225
+ fn=make_guess,
226
+ inputs=[guess_input, history_table],
227
+ outputs=[welcome, status, attempts, reward_display, hint_display, history_table, guess_input]
228
+ )
229
+
230
+ reset_btn.click(
231
+ fn=reset_game,
232
+ inputs=[],
233
+ outputs=[welcome, status, attempts, reward_display, hint_display, history_table]
234
+ )
235
+
236
+ # Footer
237
+ gr.Markdown(
238
+ """
239
+ ---
240
+
241
+ Built with [OpenEnv](https://github.com/meta-pytorch/OpenEnv) |
242
+ Powered by [Gradio](https://gradio.app) |
243
+ Deployed on [Hugging Face Spaces](https://huggingface.co/spaces)
244
+ """
245
+ )
246
+
247
+ return demo
248
+
249
+
250
+ # Create the Gradio app
251
+ gradio_app = create_gradio_interface()
252
+
253
+ if __name__ == "__main__":
254
+ # For local testing
255
+ gradio_app.launch(server_name="0.0.0.0", server_port=7860)
server/requirements.txt CHANGED
@@ -3,6 +3,7 @@ fastapi>=0.104.0
3
  uvicorn>=0.24.0
4
  pydantic>=2.0.0
5
  requests>=2.25.0
 
6
 
7
  # For openenv-core if not using in-repo imports
8
  # openenv-core>=0.1.0
 
3
  uvicorn>=0.24.0
4
  pydantic>=2.0.0
5
  requests>=2.25.0
6
+ gradio>=4.0.0
7
 
8
  # For openenv-core if not using in-repo imports
9
  # openenv-core>=0.1.0
server/standalone_app.py CHANGED
@@ -216,6 +216,17 @@ app = FastAPI(title="Number Guessing Game Environment")
216
  # Create environment instance
217
  env = NumberGuessEnvironment()
218
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
  @app.get("/")
221
  async def root():
 
216
  # Create environment instance
217
  env = NumberGuessEnvironment()
218
 
219
+ # Import and mount Gradio interface at /web
220
+ try:
221
+ from gradio_ui import gradio_app
222
+ import gradio as gr
223
+
224
+ # Mount Gradio app at /web path
225
+ app = gr.mount_gradio_app(app, gradio_app, path="/web")
226
+ except ImportError:
227
+ # Gradio not available, skip web interface
228
+ pass
229
+
230
 
231
  @app.get("/")
232
  async def root():