Skip to main content

Latest Tag Pypi version

Type Hints Code Formatting Pytest

Type Hints Code Formatting Pytest PytestCoverage

Supported OS Python Version Latest Repo Update

License

ContaineRL

Containerize your RL Environments and Agents

Overview

ContaineRL is a toolkit to package and deploy reinforcement-learning (RL) environments and agents inside reproducible containers. It provides a compact Python API and a command-line interface (entry point: containerl-cli) to manage environment/agent lifecycles, build artifacts, and integrate with gRPC/msgpack-based interfaces.

Project layout

  • src/
    • containerl/ (package)
      • cli.py # CLI entry point (containerl.cli:main)
      • interface/ # Proto/gRPC bindings and transport abstractions
      • environment/ # Environment adapters and helpers
      • agent/ # Agent runners and integration code
  • tests/
    • unit/ # Fast, isolated unit tests (no external services)
    • integration/ # Slower tests that exercise containers, gRPC, networks
  • examples/ # Example agents and environments

Installation

Install for development:

  • Python 3.12+ is required, UV is strongly suggested.
  • Clone and install editable:
uv sync --dev

This installs the containerl-cli console script (defined in pyproject.toml) and dev tools (pyright, pytest, ruff, etc.).

Quickstart (Python Package)

ContaineRL provides simple abstractions to expose RL environments and agents as containerized services.

Exposing an Environment

Wrap your environment class (Gymnasium-compatible) and expose it via gRPC:

import gymnasium as gym
from containerl import AllowedTypes, AllowedInfoValueTypes, create_environment_server

class Environment(gym.Env):
    def __init__(self, render_mode: str, env_name: str):
        self._env = gym.make(env_name, render_mode=render_mode)
        self.observation_space = gym.spaces.Dict({"observation": self._env.observation_space})
        self.action_space = self._env.action_space

    def reset(self, *, seed=None, options=None):
        obs, info = self._env.reset(seed=seed, options=options)
        return {"observation": obs}, info

    def step(self, action):
        obs, reward, terminated, truncated, info = self._env.step(action)
        return {"observation": obs}, float(reward), terminated, truncated, info

if __name__ == "__main__":
    create_environment_server(Environment)

Run this script as your Docker container entrypoint. The server listens on port 50051 by default.

Exposing an Agent

Implement the CRLAgent interface and expose it via gRPC:

import numpy as np
from gymnasium import spaces
from containerl import CRLAgent, AllowedTypes, create_agent_server

class Agent(CRLAgent):
    def __init__(self, target: float, gain: float):
        self.target = target
        self.gain = gain
        self.observation_space = spaces.Dict({"state": spaces.Box(0, 100, shape=(1,))})
        self.action_space = spaces.Box(0, 10, shape=(1,), dtype=np.float32)

    def get_action(self, observation: dict[str, AllowedTypes]) -> AllowedTypes:
        return np.clip(self.gain * (self.target - observation["state"]), 0, 10)

if __name__ == "__main__":
    create_agent_server(Agent)

Both create_environment_server and create_agent_server handle initialization arguments passed via gRPC, spawn the service, and manage the lifecycle automatically.

See more examples provided with the repository in the examples/ directory.

Quickstart (CLI)

Show help and global options:

uv run containerl-cli --help

Common, supported commands (see --help for full options):

Build a Docker image from a directory containing a Dockerfile:

uv run containerl-cli build ./examples/gymnasium/environments/atari/ -n my-image -t v1

Run a built image (maps container port 50051 to host by default):

# Run with explicit image name
uv run containerl-cli run my-image:v1

# Run with a custom container name (only when count=1)
uv run containerl-cli run my-image:v1 --name my-container

# Run multiple containers
uv run containerl-cli run my-image:v1 --count 3

# Run in interactive mode (only when count=1)
uv run containerl-cli run my-image:v1 -i

Test connection to a running container:

# Test with initialization arguments
uv run containerl-cli test --address localhost:50051 \
  --init-arg render_mode="rgb_array" \
  --init-arg env_name="ALE/Breakout-v5" \
  --init-arg obs_type="ram"

Build an image and run containers from it:

uv run containerl-cli build-run ./examples/gymnasium/environments/atari/

# With a custom container name
uv run containerl-cli build-run ./examples/gymnasium/environments/atari/ --container-name my-env

Build, run and test a container (invokes client checks):

# With initialization arguments (supports int, float, bool, and string values)
uv run containerl-cli build-run-test ./examples/gymnasium/environments/atari/ \
  --init-arg render_mode="rgb_array" \
  --init-arg env_name="ALE/Breakout-v5" \
  --init-arg obs_type="ram"

Stop containers by image or by name:

# Stop all containers started from a given image
uv run containerl-cli stop --image my-image:v1

# Stop container(s) by name
uv run containerl-cli stop --name my-container

The CLI subcommands implemented are: build, run, test, stop, build-run, and build-run-test. Use containerl-cli <command> --help for command-specific flags.

Important notes:

  • The default image name is containerl-build:latest (used when no name is specified in build or run commands)
  • Container naming (--name for run, --container-name for build-run/build-run-test), volume mounting (--volume), interactive mode (-i), and attach mode (-a) are only available when --count 1 (the default)
  • The stop command requires either --image or --name but not both
  • Initialization arguments (--init-arg key=value) can be passed to test and build-run-test commands to configure the environment or agent. Multiple init args can be specified, and values are automatically converted to int, float, bool, or string types

Testing strategy (unit vs integration)

The repository separates tests into two folders: tests/unit/ and tests/integration/ to speed up the inner development loop and to make CI scheduling simpler.

Unit tests: fast, deterministic, no network or container dependencies. Run quickly on every commit:

pytest tests/unit

Integration tests: exercise containers, gRPC interfaces, or external services. Run them less frequently or in dedicated CI jobs:

pytest tests/integration

License & Contact

This project is MIT licensed. For questions or issues open an issue at the repository or contact the maintainer listed in pyproject.toml.

Containerize your RL Environments and Agents

Metadata

Release files for containerl 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for containerl 0.1.3
File Size Uploaded Provenance Actions
containerl-0.1.3.tar.gz 31.2 kB Without provenance Details for containerl-0.1.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for containerl 0.1.3
File Interpreter ABI Platform Actions
containerl-0.1.3-py3-none-any.whl Python 3 none any Details for containerl-0.1.3-py3-none-any.whl

Total release size: 68.8 kB

Release files / containerl-0.1.3.tar.gz

Download URL containerl-0.1.3.tar.gz
Size 31.2 kB
Tags Source
SHA-256 checksum
How to use checksums
fd1e9d4c147d43f38077939b098ee57ae057dd589180d25d3537e1364c584404
BLAKE2b-256 checksum
How to use checksums
260a49b15a8709cd5098c43afcb104011fcb33697c25ac60d4d8b84c6d77a184
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / containerl-0.1.3-py3-none-any.whl

Download URL containerl-0.1.3-py3-none-any.whl
Size 37.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
444aeafcd8b13f611d54f35c2e2a94ed73d5fd7f692e9223918ffcca90a84ce0
BLAKE2b-256 checksum
How to use checksums
09ee5b353066430da0a595d21c7dfe80b6ff528680efd8211e6a14d20540f3fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for containerl 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page