CoolFace
Apppublic

hanabhi/gridworld-env

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
openapp_example.py363 linesDownload Raw Back to examples
1#!/usr/bin/env python32# Copyright (c) Meta Platforms, Inc. and affiliates.3# All rights reserved.4#5# This source code is licensed under the BSD-style license found in the6# LICENSE file in the root directory of this source tree.7 8"""9Example usage of the OpenApp Environment.10 11This script demonstrates how to use the OpenApp environment with OpenEnv.12It can be run in two modes:131. With Docker: Uses the Docker image to run the environment142. Local: Directly uses the OpenAppEnvironment class (requires OpenApps installed)15 16Usage:17    # Run with Docker (recommended)18    python examples/openapp_example.py --mode docker19 20    # Run locally without Docker21    python examples/openapp_example.py --mode local22 23    # Run with custom number of steps24    python examples/openapp_example.py --mode docker --num-steps 2025 26Visualization Options:27    # To SEE the browser window and watch agent interactions in real-time:28    #29    # Terminal 1: Start OpenApps server with visible browser30    cd OpenApps31    python OpenApps/launch.py browsergym_env_args.headless=False32 33    # Terminal 2: Run your agent code34    export OPENAPPS_URL=http://localhost:500135    python examples/openapp_example.py --mode local36 37    # Or access the web interface directly in your browser:38    # - OpenApps: http://localhost:500139    # - Calendar: http://localhost:5001/calendar40    # - Todo: http://localhost:5001/todo41    # - Messenger: http://localhost:5001/messages42    # - Maps: http://localhost:5001/maps43 44    # Docker mode web interface45    # - Web UI: http://localhost:8000/web46    # - API docs: http://localhost:8000/docs47 48Important:49    The browser visualization is controlled by the OpenApps SERVER, not the client.50    You must launch the server with 'browsergym_env_args.headless=False' to see51    the browser window.52"""53 54import argparse55import os56import sys57import time58from pathlib import Path59 60# Add src to path61sys.path.insert(0, str(Path(__file__).parent.parent))62 63 64def run_with_docker(num_steps: int = 15, headless: bool = True):65    """Run OpenApp environment using Docker container."""66    from openapp_env import OpenAppAction, OpenAppEnv67 68    print("=" * 70)69    print("Starting OpenApp environment with Docker...")70    print(f"Headless mode: {headless}")71    print("=" * 70)72 73    try:74        # Create environment from Docker image75        env = OpenAppEnv.from_docker_image("openapp-env:latest")76 77        # Reset to start a new session78        print("\n[1/4] Resetting environment...")79        result = env.reset()80        print(f"✓ Environment reset")81        print(f"  Starting URL: {result.observation.url}")82        print(f"  Open pages: {len(result.observation.open_pages_urls)}")83        print(f"  HTML length: {len(result.observation.html)} characters")84 85        # Example actions to demonstrate different action types86        actions = [87            {88                "description": "Navigate to calendar app",89                "action": OpenAppAction(90                    action_type="goto", url="http://localhost:5001/calendar"91                ),92            },93            {94                "description": "Scroll down to see more content",95                "action": OpenAppAction(action_type="scroll", direction="down"),96            },97            {98                "description": "Navigate to todo app",99                "action": OpenAppAction(100                    action_type="goto", url="http://localhost:5001/todo"101                ),102            },103            {104                "description": "Navigate to messenger app",105                "action": OpenAppAction(106                    action_type="goto", url="http://localhost:5001/messenger"107                ),108            },109            {110                "description": "Navigate to maps app",111                "action": OpenAppAction(112                    action_type="goto", url="http://localhost:5001/maps"113                ),114            },115            {116                "description": "Navigate back to home",117                "action": OpenAppAction(118                    action_type="goto", url="http://localhost:5001"119                ),120            },121        ]122 123        # Run demonstration steps124        print(f"\n[2/4] Running {min(num_steps, len(actions))} demonstration steps...")125        for i, action_info in enumerate(actions[:num_steps]):126            print(f"\nStep {i+1}: {action_info['description']}")127            print(f"  Action type: {action_info['action'].action_type}")128 129            result = env.step(action_info["action"])130 131            print(f"  ✓ Action executed")132            print(f"    Current URL: {result.observation.url}")133            print(f"    Reward: {result.reward}")134            print(f"    Done: {result.done}")135 136            if result.observation.last_action_error:137                print(f"    ⚠️  Error: {result.observation.last_action_error}")138 139            # Check app state if available140            if result.observation.app_state:141                print(142                    f"    App state keys: {list(result.observation.app_state.keys())}"143                )144 145            # Small delay for readability146            time.sleep(0.5)147 148            if result.done:149                print(f"\n✓ Episode finished at step {i+1}!")150                break151 152        # Get final state153        print(f"\n[3/4] Getting final environment state...")154        state = env.state()155        print(f"✓ Final state:")156        print(f"  Episode ID: {state.episode_id}")157        print(f"  Total steps: {state.step_count}")158 159        # Summary160        print(f"\n[4/4] Session Summary:")161        print(f"  Steps taken: {state.step_count}")162        print(f"  Final URL: {result.observation.url}")163        print(f"  Episode complete: {result.done}")164 165        # Web interface info166        print(f"\n" + "=" * 70)167        print(f"💡 TIP: Access the web interface at http://localhost:8000/web")168        print(f"    - Interactive UI for manual testing")169        print(f"    - API documentation at http://localhost:8000/docs")170        print(f"=" * 70)171 172    except Exception as e:173        print(f"\n❌ Error: {e}")174        import traceback175 176        traceback.print_exc()177        return 1178    finally:179        print("\n[Cleanup] Closing environment...")180        env.close()181        print("✓ Environment closed")182 183    return 0184 185 186def run_local(num_steps: int = 15, headless: bool = True):187    """Run OpenApp environment locally without Docker."""188 189    # Check if OPENAPPS_URL is set190    if not os.environ.get("OPENAPPS_URL"):191        print("=" * 70)192        print("❌ ERROR: OPENAPPS_URL not set")193        print("=" * 70)194        print("\nLocal mode requires OpenApps server to be running.")195        print("\nPlease follow these steps:")196        print("\n1. Start OpenApps server in a separate terminal:")197        print("   cd /path/to/OpenApps")198        print("   uv run launch.py")199        print("\n2. Set the OPENAPPS_URL environment variable:")200        print("   export OPENAPPS_URL=http://localhost:5001")201        print("\n3. Run this script again:")202        print("   python examples/openapp_example.py --mode local")203        print("\nAlternatively, use Docker mode (recommended):")204        print("   python examples/openapp_example.py --mode docker")205        print("=" * 70)206        return 1207 208    try:209        # NOTE: This example imports from the server module directly for local development.210        # This is intentional for local testing/debugging where no HTTP server is involved.211        # In production, use the client API (OpenAppEnv) which communicates over HTTP/WebSocket.212        # See run_with_docker() for the recommended production pattern.213        from openapp_env.models import OpenAppAction214        from openapp_env.server.openapp_environment import OpenAppEnvironment215    except ImportError as e:216        print(f"❌ Error importing local modules: {e}")217        print("\nMake sure you have installed the environment:")218        print("  cd envs/openapp_env")219        print("  pip install -e .")220        return 1221 222    print("=" * 70)223    print("Starting OpenApp environment locally...")224    print(f"Using OpenApps server at: {os.environ.get('OPENAPPS_URL')}")225    print(f"Headless mode: {headless}")226    print("=" * 70)227 228    try:229        # Create environment locally230        print("\n[1/4] Initializing local environment...")231        env = OpenAppEnvironment(232            openapps_url=os.environ.get("OPENAPPS_URL"),233            headless=headless,234            max_steps=50,235        )236 237        # Reset environment238        print("\n[2/4] Resetting environment...")239        result = env.reset()240        print(f"✓ Environment reset")241        print(f"  Starting URL: {result.url}")242        print(f"  HTML length: {len(result.html)} characters")243 244        # Take some example steps245        print(f"\n[3/4] Running {num_steps} steps...")246        for i in range(num_steps):247            # Simple actions for demonstration248            actions = [249                OpenAppAction(250                    action_type="goto", url=f"{os.environ.get('OPENAPPS_URL')}/calendar"251                ),252                OpenAppAction(action_type="scroll", direction="down"),253                OpenAppAction(254                    action_type="goto", url=f"{os.environ.get('OPENAPPS_URL')}/todo"255                ),256                OpenAppAction(action_type="noop"),257            ]258 259            action = actions[i % len(actions)]260            result = env.step(action)261 262            if i % 5 == 0 or result.done:263                print(f"Step {i+1}:")264                print(f"  Action: {action.action_type}")265                print(f"  URL: {result.url}")266                print(f"  Reward: {result.reward}")267                print(f"  Done: {result.done}")268 269            if result.done:270                print(f"\n✓ Episode finished at step {i+1}!")271                break272 273        # Get final state274        print(f"\n[4/4] Final state:")275        print(f"  Episode ID: {env.state.episode_id}")276        print(f"  Total steps: {env.state.step_count}")277 278    except Exception as e:279        print(f"\n❌ Error: {e}")280        import traceback281 282        traceback.print_exc()283        return 1284    finally:285        print("\n[Cleanup] Closing environment...")286        env.close()287        print("✓ Environment closed")288 289    return 0290 291 292def main():293    parser = argparse.ArgumentParser(294        description="OpenApp Environment Example",295        formatter_class=argparse.RawDescriptionHelpFormatter,296        epilog="""297Examples:298  # Run with Docker (recommended)299  python examples/openapp_example.py --mode docker300 301  # Run locally without Docker302  python examples/openapp_example.py --mode local303 304  # Show browser window to visualize agent actions305  python examples/openapp_example.py --mode local --show-browser306 307  # Run with custom number of steps308  python examples/openapp_example.py --mode docker --num-steps 20309 310Visualization:311  - Use --show-browser to see the browser window and watch agent interactions312  - Access OpenApps web interface at http://localhost:5001 (when server is running)313  - Docker mode web interface: http://localhost:8000/web314 315Note:316  - Docker mode requires: docker build -t openapp-env:latest -f envs/openapp_env/server/Dockerfile envs/openapp_env317  - Local mode requires: pip install -e envs/openapp_env && playwright install chromium318        """,319    )320 321    parser.add_argument(322        "--mode",323        choices=["docker", "local"],324        default="docker",325        help="Run mode: 'docker' (recommended) or 'local'",326    )327    parser.add_argument(328        "--num-steps", type=int, default=15, help="Number of steps to run (default: 15)"329    )330    parser.add_argument(331        "--headless",332        action="store_true",333        default=False,334        help="Run browser in headless mode (no visible window)",335    )336    parser.add_argument(337        "--show-browser",338        action="store_true",339        default=False,340        help="Show browser window (opposite of --headless, easier to remember)",341    )342 343    args = parser.parse_args()344 345    # Determine headless mode: default to True unless --show-browser is used346    headless = not args.show_browser if args.show_browser else args.headless347 348    print("\n" + "=" * 70)349    print("OpenApp Environment Example")350    print("=" * 70)351    print(f"Mode: {args.mode}")352    print(f"Steps: {args.num_steps}")353    print(f"Headless: {headless}")354 355    if args.mode == "docker":356        return run_with_docker(args.num_steps, headless)357    else:358        return run_local(args.num_steps, headless)359 360 361if __name__ == "__main__":362    sys.exit(main())363