- openenv¶
Maze Environment¶
A gridworld maze where the agent must navigate from a start cell to an exit while avoiding walls.
Maze Layout¶
The default environment ships with a single 8x8 maze:
0 0 0 0 0 1 0 0
1 1 0 1 0 1 0 1
0 0 0 1 0 0 0 1
0 1 1 1 1 1 0 0
0 0 0 0 0 0 1 0
1 0 1 1 1 0 0 0
0 0 0 0 1 0 1 0
0 1 1 0 0 0 0 0
0 is an empty cell and 1 is a wall. Coordinates are (col, row) with (0, 0) at the upper-left.
Quick Start¶
The simplest way to use the Maze environment is through the MazeEnv client:
from maze_env import MazeAction, MazeEnv
try:
# Create environment from Docker image
env = MazeEnv.from_docker_image("maze_env-env:latest")
# Reset to start a new episode
result = env.reset()
print(f"Start position: {result.observation.current_position}")
print(f"Legal actions: {result.observation.legal_actions}")
# Play until done
while not result.done:
action_id = result.observation.legal_actions[0]
result = env.step(MazeAction(action=action_id))
print(f"Position: {result.observation.current_position}")
print(f"Reward: {result.reward}, Done: {result.done}")
finally:
# Always clean up
env.close()
That's it! The MazeEnv.from_docker_image() method handles:
- Starting the Docker container
- Waiting for the server to be ready
- Connecting to the environment
- Container cleanup when you call close()
Building the Docker Image¶
From the environment directory (envs/maze_env/):
docker build -t maze_env-env:latest -f server/Dockerfile .
Deploying to Hugging Face Spaces¶
You can easily deploy your OpenEnv environment to Hugging Face Spaces using the openenv push command:
# From the environment directory (envs/maze_env/)
openenv push
# Or specify options
openenv push --namespace my-org --private
The openenv push command will:
1. Validate that the directory is an OpenEnv environment (checks for openenv.yaml)
2. Prepare a custom build for Hugging Face Docker space (enables web interface)
3. Upload to Hugging Face (ensuring you're logged in)
Prerequisites¶
- Authenticate with Hugging Face: The command will prompt for login if not already authenticated
Options¶
--directory,-d: Directory containing the OpenEnv environment (defaults to current directory)--repo-id,-r: Repository ID in format 'username/repo-name' (defaults to 'username/env-name' from openenv.yaml)--base-image,-b: Base Docker image to use (overrides Dockerfile FROM)--private: Deploy the space as private (default: public)
Examples¶
# Push to your personal namespace (defaults to username/env-name from openenv.yaml)
openenv push
# Push to a specific repository
openenv push --repo-id my-org/maze-env
# Push with a custom base image
openenv push --base-image ghcr.io/meta-pytorch/openenv-base:latest
# Push as a private space
openenv push --private
# Combine options
openenv push --repo-id my-org/maze-env --base-image custom-base:latest --private
After deployment, your space will be available at:
https://huggingface.co/spaces/<repo-id>
Running the Default Maze¶
docker run -p 8000:8000 maze_env-env:latest
Environment Details¶
Action¶
MazeAction: Contains a single field
- action (int) - Movement action
- 0 = move up
- 1 = move down
- 2 = move left
- 3 = move right
Observation¶
MazeObservation: Per-step observation payload
- current_position (List[int]) - Agent position as [col, row]
- legal_actions (List[int]) - Valid actions from the current position
- metadata (dict) - Extra info:
- maze: 2D grid (0 = empty, 1 = wall)
- status: "playing", "win", or "lose"
- exit_cell: Exit position as [col, row]
- step: Current step count
State¶
MazeState: Server-side state snapshot
- episode_id (str) - Unique identifier for the current episode
- step_count (int) - Number of steps taken
- done (bool) - Whether the episode has ended
- current_position (List[int]) - Current agent position
- exit_cell (List[int]) - Exit position
- status (str) - "playing", "win", or "lose"
Reward¶
The reward follows the underlying maze rules:
- Small penalty for a move (-0.05)
- Penalty for revisiting a cell (-0.25)
- Penalty for invalid move (-0.75)
- Reward for reaching the exit (+10.0)
Configuration¶
Environment Variables¶
This environment does not rely on environment variables. Customize the maze in code (see Development & Testing).
Advanced Usage¶
Connecting to an Existing Server¶
If you already have a Maze environment server running:
from maze_env import MazeAction, MazeEnv
# Connect to existing server
env = MazeEnv(base_url="http://localhost:8000")
# Use as normal
result = env.reset()
result = env.step(MazeAction(action=result.observation.legal_actions[0]))
# Close connection (does NOT stop the server)
env.close()
Connecting to HuggingFace Space¶
from maze_env import MazeAction, MazeEnv
# Connect to remote Space
env = MazeEnv(base_url="https://your-username-maze-env.hf.space")
result = env.reset()
print(f"Position: {result.observation.current_position}")
print(f"Legal actions: {result.observation.legal_actions}")
result = env.step(MazeAction(action=result.observation.legal_actions[0]))
env.close()
Project Structure¶
maze_env/
├── __init__.py # Module exports
├── README.md # This file
├── openenv.yaml # OpenEnv manifest
├── pyproject.toml # Project metadata and dependencies
├── client.py # MazeEnv client implementation
├── models.py # Action, Observation, and State models
└── server/
├── __init__.py # Server module exports
├── maze.py # Maze logic and rewards
├── maze_env_environment.py # Core environment implementation
├── app.py # FastAPI application
└── Dockerfile # Environment container