Serve an Environment¶
Use rlmesh.EnvServer to expose a Gymnasium-style environment over an endpoint.
import gymnasium as gym
import rlmesh
env = gym.make("CartPole-v1")
server = rlmesh.EnvServer(env, "127.0.0.1:5555")
server.serve()
serve() blocks. Use start() when the current process needs to keep doing other work:
server = rlmesh.EnvServer(env, port=5555)
server.start()
print(server.address)
server.wait()
Environment Shape¶
RLMesh works with standard Gymnasium environments from gym.make(...) and with custom objects that
follow the same shape:
observation_spaceaction_spacereset(seed=None, options=None) -> (obs, info)step(action) -> (obs, reward, terminated, truncated, info)close()
Vectorized environments can expose num_envs, single_observation_space, and
single_action_space.
Common Gymnasium wrappers can stay in place. RLMesh reads the spaces and calls the wrapped methods through the normal Gymnasium API.
Environment Contract¶
When EnvServer wraps the environment, it creates an EnvContract. Clients
receive that contract during connection.
server = rlmesh.EnvServer(env, "127.0.0.1:5555")
contract = server.env_contract
print(contract.id)
print(contract.observation_space.kind)
print(contract.action_space.kind)
print(contract.num_envs)
server.spec is an alias for server.env_contract. See Contracts and Specs for contract
fields.
Addresses¶
Use an explicit address string:
rlmesh.EnvServer(env, "tcp://127.0.0.1:5555")
rlmesh.EnvServer(env, "127.0.0.1:5555")
rlmesh.EnvServer(env, "unix:///tmp/rlmesh-env.sock")
Or use helpers:
rlmesh.EnvServer(env, host="127.0.0.1", port=5555)
rlmesh.EnvServer(env, path="/tmp/rlmesh-env.sock")
Readiness¶
RLMesh exposes two machine-readable readiness signals. Use them instead of parsing startup prints; the human-readable output is not a stable interface.
gRPC Health Service¶
RLMesh’s Rust gRPC serve paths serve the standard
grpc.health.v1 health service,
separate from the env/model RPCs. Overall server health, the empty "" service name, reports
SERVING once the listener accepts connections.
Any standard health client can probe it, for example with
grpc-health-probe:
grpc-health-probe -addr 127.0.0.1:5555
# status: SERVING
Use this for long-lived deployments and container readiness probes.
Note
The Rust EnvServer / ModelWorker serve paths register the health service
today. The Python rlmesh.EnvServer wrapper is gaining the same registration;
until that lands, use the ready file descriptor below for the Python CLI path.
Ready File Descriptor (CLI)¶
The env-serve CLI (python -m rlmesh._cli.serve_env) accepts --ready-fd <int>. RLMesh writes one
line containing the resolved bind address, for example tcp://127.0.0.1:54321, then closes the file
descriptor. This works when the bind port is 0 because the line carries the resolved address.
# Open fd 3 onto a file, point --ready-fd at it, then read the address back.
# Use a dedicated fd (not stdout/1) so the address line is not mixed with the
# human-readable startup prints.
exec 3>/tmp/rlmesh-ready
python -m rlmesh._cli.serve_env --env CartPole-v1 \
--address tcp://127.0.0.1:0 --ready-fd 3 &
exec 3>&- # close our copy so EOF propagates
addr=$(head -n1 /tmp/rlmesh-ready) # the resolved bind address
echo "ready at $addr"
Python embedders can call rlmesh._cli.serve_env.write_ready_fd directly.