|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""FastAPI application entrypoint for the TextArena environment.""" |
|
|
|
|
|
from __future__ import annotations |
|
|
|
|
|
import os |
|
|
|
|
|
from openenv.core.env_server.http_server import create_app |
|
|
|
|
|
try: |
|
|
|
|
|
from textarena_env.models import TextArenaAction, TextArenaObservation |
|
|
from textarena_env.server.environment import TextArenaEnvironment |
|
|
except ImportError: |
|
|
|
|
|
from models import TextArenaAction, TextArenaObservation |
|
|
from .environment import TextArenaEnvironment |
|
|
|
|
|
|
|
|
def _parse_env_kwargs(prefix: str = "TEXTARENA_KW_") -> dict[str, str]: |
|
|
"""Collect arbitrary environment kwargs from the process environment.""" |
|
|
|
|
|
env_kwargs: dict[str, str] = {} |
|
|
for key, value in os.environ.items(): |
|
|
if key.startswith(prefix): |
|
|
env_key = key[len(prefix) :].lower() |
|
|
env_kwargs[env_key] = value |
|
|
return env_kwargs |
|
|
|
|
|
|
|
|
env_id = os.getenv("TEXTARENA_ENV_ID", "Wordle-v0") |
|
|
num_players = int(os.getenv("TEXTARENA_NUM_PLAYERS", "1")) |
|
|
max_turns_env = os.getenv("TEXTARENA_MAX_TURNS") |
|
|
max_turns = int(max_turns_env) if max_turns_env is not None else None |
|
|
download_nltk = os.getenv("TEXTARENA_DOWNLOAD_NLTK", "1") in {"1", "true", "True"} |
|
|
|
|
|
extra_kwargs = _parse_env_kwargs() |
|
|
|
|
|
|
|
|
|
|
|
def create_textarena_environment(): |
|
|
"""Factory function that creates TextArenaEnvironment with config.""" |
|
|
return TextArenaEnvironment( |
|
|
env_id=env_id, |
|
|
num_players=num_players, |
|
|
max_turns=max_turns, |
|
|
download_nltk=download_nltk, |
|
|
env_kwargs=extra_kwargs, |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app = create_app( |
|
|
create_textarena_environment, |
|
|
TextArenaAction, |
|
|
TextArenaObservation, |
|
|
env_name="textarena_env", |
|
|
) |
|
|
|
|
|
|
|
|
def main(host: str = "0.0.0.0", port: int = 8000): |
|
|
""" |
|
|
Entry point for direct execution via uv run or python -m. |
|
|
|
|
|
This function enables running the server without Docker: |
|
|
uv run --project . server |
|
|
uv run --project . server --port 8001 |
|
|
python -m textarena.server.app |
|
|
|
|
|
Args: |
|
|
host: Host address to bind to (default: "0.0.0.0") |
|
|
port: Port number to listen on (default: 8000) |
|
|
|
|
|
For production deployments, consider using uvicorn directly with |
|
|
multiple workers: |
|
|
uvicorn textarena.server.app:app --workers 4 |
|
|
""" |
|
|
import uvicorn |
|
|
|
|
|
uvicorn.run(app, host=host, port=port) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
main() |
|
|
|