NeoCodes-dev's picture
Upload folder using huggingface_hub
ac5cfba verified
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
"""
FastAPI application for the Pokemon Red Environment.
This module creates an HTTP server that exposes the PokemonRedEnvironment
over HTTP and WebSocket endpoints, compatible with EnvClient.
Endpoints:
- POST /reset: Reset the environment
- POST /step: Execute an action
- GET /state: Get current environment state
- GET /schema: Get action/observation schemas
- WS /ws: WebSocket endpoint for persistent sessions
Usage:
# Development (with auto-reload):
uvicorn server.app:app --reload --host 0.0.0.0 --port 8000
# Production:
uvicorn server.app:app --host 0.0.0.0 --port 8000 --workers 4
Environment variables:
POKEMON_HEADLESS: Run emulator without display (default: "true")
POKEMON_ACTION_FREQ: Emulator ticks per action (default: "24")
POKEMON_ROM_PATH: Path to Pokemon Red ROM (default: "/app/env/server/PokemonRed.gb")
POKEMON_INIT_STATE: Path to initial save state (default: "/app/env/server/init.state")
POKEMON_MAX_STEPS: Maximum steps per episode (default: "163840")
"""
import os
from openenv.core.env_server import create_app
# Support both package imports (when used as package) and direct imports (Docker/standalone)
# Try relative imports first (package mode), fall back to absolute (Docker/standalone mode)
try:
from ..models import PokemonRedAction, PokemonRedObservation
from ..config import PokemonRedConfig
from .pokemonred_env_environment import PokemonRedEnvironment
except ImportError:
# Fallback for standalone loading (Docker, openenv validate, etc.)
from models import PokemonRedAction, PokemonRedObservation
from config import PokemonRedConfig
from server.pokemonred_env_environment import PokemonRedEnvironment
def create_pokemon_environment():
"""
Factory function that creates PokemonRedEnvironment with config from env vars.
This enables WebSocket session support where each client gets their own
environment instance with isolated state.
"""
config = PokemonRedConfig(
headless=os.getenv("POKEMON_HEADLESS", "true").lower() == "true",
action_freq=int(os.getenv("POKEMON_ACTION_FREQ", "24")),
gb_path=os.getenv("POKEMON_ROM_PATH", "/app/env/server/PokemonRed.gb"),
init_state=os.getenv("POKEMON_INIT_STATE", "/app/env/server/init.state"),
max_steps=int(os.getenv("POKEMON_MAX_STEPS", "163840")),
session_path=os.getenv("POKEMON_SESSION_PATH", "/tmp/pokemon_sessions"),
)
return PokemonRedEnvironment(config)
# Create the FastAPI app with web interface and README integration
# Pass the factory function for WebSocket session support
app = create_app(
create_pokemon_environment,
PokemonRedAction,
PokemonRedObservation,
env_name="pokemonred",
)
def main(host: str = "0.0.0.0", port: int = 8000):
"""
Entry point for direct execution.
This function is required by openenv validate for uv_run and python_module
deployment modes.
Args:
host: Host address to bind to (default: "0.0.0.0")
port: Port number to listen on (default: 8000)
"""
import uvicorn
uvicorn.run(app, host=host, port=port)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Pokemon Red OpenEnv Server")
parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to bind")
parser.add_argument("--port", type=int, default=8000, help="Port to listen on")
args = parser.parse_args()
# Call main() - openenv validate checks for literal 'main()' string
main()