Skip to content

Commit 3500a3e

Browse files
committed
update echo_env for the new standard
1 parent 9ffa1de commit 3500a3e

File tree

8 files changed

+823
-27
lines changed

8 files changed

+823
-27
lines changed

src/envs/echo_env/client.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,19 @@
1313

1414
from typing import Any, Dict
1515

16-
from core.client_types import StepResult
17-
18-
from core.env_server.types import State
19-
from core.http_env_client import HTTPEnvClient
20-
21-
from .models import EchoAction, EchoObservation
16+
# Support both in-repo and standalone imports
17+
try:
18+
# In-repo imports (when running from OpenEnv repository)
19+
from core.client_types import StepResult
20+
from core.env_server.types import State
21+
from core.http_env_client import HTTPEnvClient
22+
from .models import EchoAction, EchoObservation
23+
except ImportError:
24+
# Standalone imports (when environment is standalone with openenv-core from pip)
25+
from openenv_core.client_types import StepResult
26+
from openenv_core.env_server.types import State
27+
from openenv_core.http_env_client import HTTPEnvClient
28+
from models import EchoAction, EchoObservation
2229

2330

2431
class EchoEnv(HTTPEnvClient[EchoAction, EchoObservation]):

src/envs/echo_env/models.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@
1212

1313
from dataclasses import dataclass
1414

15-
from core.env_server.types import Action, Observation
15+
# Support both in-repo and standalone imports
16+
try:
17+
# In-repo imports (when running from OpenEnv repository)
18+
from core.env_server.types import Action, Observation
19+
except ImportError:
20+
# Standalone imports (when environment is standalone with openenv-core from pip)
21+
from openenv_core.env_server.types import Action, Observation
1622

1723

1824
@dataclass(kw_only=True)

src/envs/echo_env/openenv.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
spec_version: 1
2+
name: echo_env
3+
type: space
4+
runtime: fastapi
5+
app: server.app:app
6+
port: 8000

src/envs/echo_env/pyproject.toml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
[build-system]
8+
requires = ["setuptools>=45", "wheel"]
9+
build-backend = "setuptools.build_meta"
10+
11+
[project]
12+
name = "openenv-echo-env"
13+
version = "0.1.0"
14+
description = "Echo Environment for OpenEnv - simple test environment that echoes back messages"
15+
requires-python = ">=3.10"
16+
dependencies = [
17+
# Core OpenEnv dependencies (required for server functionality)
18+
"openenv-core>=0.1.0",
19+
"fastapi>=0.115.0",
20+
"pydantic>=2.0.0",
21+
"uvicorn>=0.24.0",
22+
"requests>=2.31.0",
23+
# No additional environment-specific dependencies needed for echo_env
24+
]
25+
26+
[project.optional-dependencies]
27+
dev = [
28+
"pytest>=8.0.0",
29+
"pytest-cov>=4.0.0",
30+
]
31+
32+
[project.scripts]
33+
# Server entry point - enables running via: uv run --project . server
34+
# or: python -m echo_env.server.app
35+
server = "echo_env.server.app:main"
36+
37+
[tool.setuptools]
38+
package-dir = {"" = "."}
39+
40+
[tool.setuptools.packages.find]
41+
where = ["."]

src/envs/echo_env/server/Dockerfile

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,65 @@
44
# This source code is licensed under the BSD-style license found in the
55
# LICENSE file in the root directory of this source tree.
66

7-
# Use the standard openenv base image
8-
# Built from: docker build -t openenv-base:latest -f src/core/containers/images/Dockerfile .
9-
# In GitHub Actions, this is overridden to use the GHCR base image
7+
# Multi-stage build using openenv-base
8+
# This Dockerfile is flexible and works for both:
9+
# - In-repo environments (with local src/core)
10+
# - Standalone environments (with openenv-core from pip)
11+
# The build script (openenv build) handles context detection and sets appropriate build args.
12+
1013
ARG BASE_IMAGE=openenv-base:latest
14+
FROM ${BASE_IMAGE} AS builder
15+
16+
WORKDIR /app
17+
18+
# Build argument to control whether we're building standalone or in-repo
19+
ARG BUILD_MODE=in-repo
20+
ARG ENV_NAME=echo_env
21+
22+
# Copy environment code (always at root of build context)
23+
COPY . /app/env
24+
25+
# For in-repo builds, openenv-core is already in the pyproject.toml dependencies
26+
# For standalone builds, openenv-core will be installed from pip via pyproject.toml
27+
WORKDIR /app/env
28+
29+
# Install dependencies using uv sync
30+
# If uv.lock exists, use it; otherwise resolve on the fly
31+
RUN --mount=type=cache,target=/root/.cache/uv \
32+
if [ -f uv.lock ]; then \
33+
uv sync --frozen --no-install-project --no-editable; \
34+
else \
35+
uv sync --no-install-project --no-editable; \
36+
fi
37+
38+
RUN --mount=type=cache,target=/root/.cache/uv \
39+
if [ -f uv.lock ]; then \
40+
uv sync --frozen --no-editable; \
41+
else \
42+
uv sync --no-editable; \
43+
fi
44+
45+
# Final runtime stage
1146
FROM ${BASE_IMAGE}
1247

13-
# Copy only what's needed for this environment
14-
COPY src/core/ /app/src/core/
15-
COPY src/envs/echo_env/ /app/src/envs/echo_env/
48+
WORKDIR /app
49+
50+
# Copy the virtual environment from builder
51+
COPY --from=builder /app/env/.venv /app/.venv
52+
53+
# Copy the environment code
54+
COPY --from=builder /app/env /app/env
55+
56+
# Set PATH to use the virtual environment
57+
ENV PATH="/app/.venv/bin:$PATH"
1658

17-
# Copy README for web interface documentation
18-
COPY src/envs/echo_env/README.md /app/README.md
59+
# Set PYTHONPATH so imports work correctly
60+
ENV PYTHONPATH="/app/env:$PYTHONPATH"
1961

2062
# Health check
2163
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
2264
CMD curl -f http://localhost:8000/health || exit 1
2365

2466
# Run the FastAPI server
25-
CMD ["uvicorn", "envs.echo_env.server.app:app", "--host", "0.0.0.0", "--port", "8000"]
67+
# The module path is constructed to work with the /app/env structure
68+
CMD ["sh", "-c", "cd /app/env && uvicorn server.app:app --host 0.0.0.0 --port 8000"]

src/envs/echo_env/server/app.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,26 @@
1212
1313
Usage:
1414
# Development (with auto-reload):
15-
uvicorn envs.echo_env.server.app:app --reload --host 0.0.0.0 --port 8000
15+
uvicorn server.app:app --reload --host 0.0.0.0 --port 8000
1616
1717
# Production:
18-
uvicorn envs.echo_env.server.app:app --host 0.0.0.0 --port 8000 --workers 4
18+
uvicorn server.app:app --host 0.0.0.0 --port 8000 --workers 4
1919
2020
# Or run directly:
21-
python -m envs.echo_env.server.app
21+
uv run --project . server
2222
"""
2323

24-
from core.env_server.http_server import create_app
25-
26-
from ..models import EchoAction, EchoObservation
27-
from .echo_environment import EchoEnvironment
24+
# Support both in-repo and standalone imports
25+
try:
26+
# In-repo imports (when running from OpenEnv repository)
27+
from core.env_server.http_server import create_app
28+
from ..models import EchoAction, EchoObservation
29+
from .echo_environment import EchoEnvironment
30+
except ImportError:
31+
# Standalone imports (when environment is standalone with openenv-core from pip)
32+
from openenv_core.env_server.http_server import create_app
33+
from models import EchoAction, EchoObservation
34+
from server.echo_environment import EchoEnvironment
2835

2936
# Create the environment instance
3037
env = EchoEnvironment()

src/envs/echo_env/server/echo_environment.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,17 @@
1313

1414
from uuid import uuid4
1515

16-
from core.env_server.interfaces import Environment
17-
from core.env_server.types import State
18-
19-
from ..models import EchoAction, EchoObservation
16+
# Support both in-repo and standalone imports
17+
try:
18+
# In-repo imports (when running from OpenEnv repository)
19+
from core.env_server.interfaces import Environment
20+
from core.env_server.types import State
21+
from ..models import EchoAction, EchoObservation
22+
except ImportError:
23+
# Standalone imports (when environment is standalone with openenv-core from pip)
24+
from openenv_core.env_server.interfaces import Environment
25+
from openenv_core.env_server.types import State
26+
from models import EchoAction, EchoObservation
2027

2128

2229
class EchoEnvironment(Environment):

0 commit comments

Comments
 (0)