The Problem Registry

See also

Making Your Code Findable

User guide page on the topic.

Exceptions Raised by the Problem Registry

Reference of all exceptions raised in this package.

These functions allow you to search and lazy-load problems.

All optimization problems should be registered exactly once. The most common way to register an optimization problem is immediately after definition. Registering your problem allows downstream users to instantiate them in a convenient and uniform manner:

>>> from cernml import coi
>>> class MyOptProblem(coi.SingleOptimizable):
...     optimization_space = ...
...     def get_initial_params(self): ...
...     def compute_single_objective(self, params): ...
...
>>> coi.register("MyOptProblem-v1", entry_point=MyOptProblem)
...
>>> env = coi.make("MyOptProblem-v1")

See the page Making Your Code Findable for a more detailed description of the concepts.

This mechanism is largely copied from the Register and Make mechanism of Gymnasium. Adjustments have been made here and there to accommodate Problem and its non-Env subclasses.

General changes:
  • Compatibility with Python 3.8 has been dropped.

  • This registry uses the entry point cernml.envs to load plugins.

  • Plugins using the entrypoints mechanism are not registered immediately upon import of this package. Instead, they’re only loaded the first time that something from their namespace is requested.

  • All warnings issued use the stacklevel argument to trace themselves back to the line that calls register() or make(). This makes it easier to find their source.

  • Instead of gymnasium.Error, a dedicated type hierarchy is used for both exceptions and warnings. All types are exposed in the cernml.coi.registration.errors module.

  • General code cleanup.

Specific changes to make():
  • isinstance checks of env_spec and env_creator.metadata have been removed or adjusted.

  • The parameter order_enforce has been added with the same override semantics as disable_env_checker.

  • A warning about the deprecated metadata key "render.modes" has been added.

  • Wrappers are only added if the wrapped environment is actually a gymnasium.Env, to keep SingleOptimizable and others safe.

  • The stacklevel parameter of warnings.warn() is threaded through the functions so that any warning is attributed to the code that called into COI (and not COI itself).

entry point group cernml.envs

Entry points defined under this group make automatic lazy loading of optimization problems possible. See Lazy Registration via Entry Points for more information and code examples.

Entry points in this group must point either at a module or at a function:

  • a module must register() its optimization problems when imported;

  • a function must register() its optimization problems when called.

Functions are specified with the syntax module_name:function_name.

In either case, all problems registered this way are added to the namespace that is given by the entry point’s name. The namespace is added automatically, it doesn’t have to be passed to register().

Whenever a namespaced problem is requested with the syntax make("namespace/problem_name", ...) and make() cannot find it, it loads the entry point associated with that namespace. This imports the entry point’s module (and if a function is given, calls that), which in turn registers a number of problems. Then make() attempts to look up the problem again.

Note

Entry points for Python packages are not to be mixed up with the entry_point argument of register().

cernml.coi.register(
env_id: str,
/,
entry_point: type[protocols.Problem] | EnvCreator | str,
vector_entry_point: VectorEnvCreator | str | None = None,
*,
reward_threshold: float | None = None,
nondeterministic: bool = False,
max_episode_steps: int | None = None,
order_enforce: bool = True,
autoreset: bool = False,
disable_env_checker: bool = False,
apply_api_compatibility: bool = False,
additional_wrappers: tuple[WrapperSpec, ...] = (),
**kwargs: Any,
) None
cernml.coi.register(
env_id: str,
/,
*,
vector_entry_point: VectorEnvCreator | str,
reward_threshold: float | None = None,
nondeterministic: bool = False,
max_episode_steps: int | None = None,
order_enforce: bool = True,
autoreset: bool = False,
disable_env_checker: bool = False,
apply_api_compatibility: bool = False,
additional_wrappers: tuple[WrapperSpec, ...] = (),
**kwargs: Any,
) None

Register an optimization problem for later use with make().

This function must be called exactly once for every problem you want to create with make().

The ID follows the syntax: [<namespace>/]<name>[-v<version>]. See make() for information how the namespace and version are used.

Parameters:
  • env_id – The ID to register the problem under.

  • entry_point – The entry point for creating the problem. May be either a subclass of Problem, a function that returns an instance of Problem, or a string. If a string, it should be in the format <module>:<object> with as many dots . on either side of the colon as necessary.

  • reward_threshold – With a reward above this threshold, an RL agent is considered to have learnt the problem.

  • nondeterministic – If True, the environment is nondeterministic; even with knowledge of the initial seed and all actions, the same state cannot be reached.

  • max_episode_steps – If not None, the maximum number of steps before an episode is truncated. Implemented via TimeLimit.

  • order_enforce – If True, a wrapper around the problem ensures that all functions are called in the correct order. Implemented via OrderEnforcing.

  • autoreset – If True, a wrapper around the problem calls reset() immediately whenever an episode ends. Implemented via AutoResetWrapper.

  • disable_env_checker – Normally, all problems are wrapped in PassiveEnvChecker. If True, don’t do that for this problem.

  • apply_api_compatibility – If True, the class still follows the Gym v0.21 Step API. In this case, StepAPICompatibility wraps around it to ensure compatibility with the new API.

  • additional_wrappers – Additional wrappers to apply to the problem automatically when make() is called.

  • vector_entry_point – The entry point for creating a vector environment. Used by make_vec().

  • **kwargs – Any further keyword arguments are passed to the problem itself upon initialization.

cernml.coi.make(
env_id: str | EnvSpec,
/,
*,
max_episode_steps: int | None = None,
autoreset: bool | None = None,
apply_api_compatibility: bool | None = None,
disable_env_checker: bool | None = None,
order_enforce: bool | None = None,
**kwargs: Any,
) protocols.Problem

Create an optimization problem according to the given ID.

The problem must have been previously registered with cernml.coi.register().

To find all available problems, use registry.all().

Unlike in register(), the ID may follow the syntax "[<module>:][<namespace>/]<name>[-v<version>]". If a module is given, it is imported unconditionally before looking up the problem.

In addition, if you don’t specify the version of a problem that has been registered with a version, the highest version is picked automatically.

If a namespace is given and the problem cannot be found immediately, an entry point in the group cernml.envs with the same name as the namespace is loaded. The entry point is expected register all its problems, including the requested one.

Parameters:
  • env_id – Name of the problem or an EnvSpec.

  • max_episode_steps – Override the same parameter of register(). Implemented via TimeLimit.

  • autoreset – If True, to automatically reset the problem after each episode. Implemented via AutoResetWrapper.

  • apply_api_compatibility – Override the same parameter of register(). Implemented via StepAPICompatibility.

  • disable_env_checker – Override the same parameter of register(). Implemented via PassiveEnvChecker.

  • order_enforce – Override the same parameter of register(). Implemented via OrderEnforcing.

  • kwargs – Additional arguments to pass to the constructor.

Returns:

An instance of the problem with wrappers applied.

Raises:

RegistryError – if the given ID doesn’t exist or the problem constructor failed.

cernml.coi.make_vec(
env_id: str | EnvSpec,
/,
*,
num_envs: int = 1,
vectorization_mode: str = 'async',
vector_kwargs: dict[str, Any] | None = None,
wrappers: Sequence[Callable[[Env], Wrapper]] | None = None,
**kwargs: Any,
) VectorEnv

Create a vector environment according to the given ID.

Note

This is a thin wrapper around gymnasium.make_vec(). The only difference is that it looks up environments in the COI registry instead of the Gym registry.

In Gymnasium, this feature is still considered experimental and likely to change in future releases.

To find all available environments, use registry.all().

Unlike in register(), the env ID may follow the syntax "[<module>:][<namespace>/]<name>[-v<version>]". If a module is given, it is imported before looking up the environment.

In addition, if you don’t specify the version of an environment that has been registered with a version, the highest version is picked automatically.

Parameters:
  • env_id – Name of the environment or an EnvSpec.

  • num_envs – Number of environments to create.

  • vectorization_mode – How to vectorize the environment. Can be either "async", "sync" or "custom".

  • vector_kwargs – Additional arguments to pass to the vectorized environment constructor.

  • wrappers – A sequence of wrapper functions to apply to the environment. Can only be used in sync or async mode.

  • **kwargs – Additional arguments to pass to the environment constructor.

Returns:

An instance of the environment.

Raises:

RegistryError – if the given ID doesn’t exist or the environment constructor failed.

cernml.coi.spec(env_id: str) EnvSpec

Retrieve the EnvSpec for a registered problem.

Parameters:

env_id – The environment ID in the usual format [<namespace>/]<name>[-v<version>].

Returns:

The environment spec.

Raises:

NotFoundError – if the spec cannot be found.

cernml.coi.pprint_registry(
*,
num_cols: int = 3,
exclude_namespaces: list[str] | None = None,
disable_print: bool = False,
) str | None

Pretty print all problems in the registry.

Keyword Arguments:
  • num_cols – The number of columns in which to print the problems.

  • exclude_namespaces – Optional. A list of namespaces to be excluded from printing.

  • disable_print – If True, print nothing and return the message as a string instead.

cernml.coi.register_envs(env_module: ModuleType)

A no-op function such that it can appear to IDEs that a module is used.

This has been re-exported from Gymnasium.

cernml.coi.registry: EnvRegistry = EnvRegistry(ep_group="cernml.envs")

The global variable that contains all registered environments. If possible, you should call the global functions instead of this variable’s methods.

Advanced Registration Features

class cernml.coi.registration.EnvRegistry(ep_group: str | None = None)

Bases: object

Class of the environment registry.

Note that this package uses its own registry, which is independent of Gymnasium’s registry. An environment registered via gymnasium.register() is not findable via cernml.coi.make() and vice versa.

To create your own, local registry, simply instantiate this class again.

Parameters:

ep_group – Optional. If passed, a string with the entry point group that should be used for namespace lookups. If not passed, no entry points are used to dynamically load environments.

property current_namespace: str | None

The current namespace as set by namespace().

namespace(ns: str, /) Iterator[None]

Context manager for modifying the current namespace.

all(
*,
ns: str | None | ~cernml.coi.registration._sentinel.Sentinel = <MISSING>,
name: str | ~cernml.coi.registration._sentinel.Sentinel = <MISSING>,
version: int | bool | None | ~cernml.coi.registration._sentinel.Sentinel = <MISSING>,
) Iterator[EnvSpec]

Yield all environment specs that match a given filter.

When called without arguments, an iterator of all environment specs is returned. Any parameter that is passed adds a filter on either the namespace, the name, or the version of the yielded specs.

Parameters:
  • ns – If passed and a string, only environment specs with that namespace are yielded. If passed and None, only environment specs without a namespace are yielded.

  • name – If passed and a string, only environment specs with the given name are yielded.

  • version – If passed and an integer, only environment specs with that exact version are yielded. If passed and True, only environment specs that have any version are yielded. If passed and False or None, only environment specs without a version are yielded.

spec(env_id: str, /) EnvSpec

Implementation of spec().

pprint(
*,
num_cols: int = 3,
exclude_namespaces: list[str] | None = None,
disable_print: bool = False,
) str | None

Implementation of pprint_registry().

register(
env_id: str,
/,
entry_point: type[protocols.Problem] | _base.EnvCreator | str | None = None,
vector_entry_point: _base.VectorEnvCreator | str | None = None,
**kwargs: Any,
) None

Implementation of register().

make(
env_id: str | EnvSpec,
/,
*,
max_episode_steps: int | None = None,
autoreset: bool | None = None,
apply_api_compatibility: bool | None = None,
disable_env_checker: bool | None = None,
order_enforce: bool | None = None,
**kwargs: Any,
) protocols.Problem

Implementation of make().

make_vec(
env_id: str | EnvSpec,
/,
num_envs: int = 1,
vectorization_mode: str = 'async',
vector_kwargs: dict[str, Any] | None = None,
wrappers: Sequence[Callable[[gymnasium.Env], gymnasium.Wrapper]] | None = None,
**kwargs: Any,
) gymnasium.experimental.vector.VectorEnv

Implementation of make_vec().

class cernml.coi.registration.EnvSpec(
id: str,
entry_point: ~gymnasium.envs.registration.EnvCreator | str | None = None,
reward_threshold: float | None = None,
nondeterministic: bool = False,
max_episode_steps: int | None = None,
order_enforce: bool = True,
autoreset: bool = False,
disable_env_checker: bool = False,
apply_api_compatibility: bool = False,
kwargs: dict[str,
~typing.Any] = <factory>,
additional_wrappers: tuple[~gymnasium.envs.registration.WrapperSpec,
...] = <factory>,
vector_entry_point: ~gymnasium.envs.registration.VectorEnvCreator | str | None = None,
)

Bases: object

Reimplementation of gymnasium.envs.registration.EnvSpec.

This dataclass is largely identical to Gymnasium’s version with exception of the following differences:

If you need a Gymnasium EnvSpec for typing purposes, you can convert this class via downcast_spec().

make(**kwargs: Any) protocols.Problem

Call coi.make() using this spec.

to_json() str

Convert this spec into a JSON-compatible string.

classmethod from_json(json_env_spec: str) Self

Convert a JSON string back into a specification stack.

pprint(
disable_print: bool = False,
include_entry_points: bool = False,
print_all: bool = False,
) str | None

Pretty prints the environment spec.

Parameters:
  • disable_print – If to disable print and return the output

  • include_entry_points – If to include the entry_points in the output

  • print_all – If to print all information, including variables with default values

Returns:

If disable_print is True a string otherwise None

class cernml.coi.registration.MinimalEnvSpec(*args, **kwargs)

Bases: Protocol

Protocol that EnvSpec objects have to follow.

to_json() str

Converts the environment spec into a json compatible string.

pprint(
disable_print: bool = False,
include_entry_points: bool = False,
print_all: bool = False,
) str | None

Pretty prints the environment spec.

cernml.coi.registration.downcast_spec(
spec: EnvSpec,
) EnvSpec

Turn a COI EnvSpec into a Gym EnvSpec.

final class cernml.coi.registration._sentinel.Sentinel(value)

Bases: Enum

Singleton sentinel type to mark arguments as unpassed.

The pattern is motivated by PEP 484 and the naming inspired by PEP 661. This is used by EnvRegistry.all().

cernml.coi.registration._sentinel.MISSING: Sentinel

Object used to mark unpassed arguments.

gymnasium.make_vec(
id: str | EnvSpec,
num_envs: int = 1,
vectorization_mode: str = 'async',
vector_kwargs: dict[str, Any] | None = None,
wrappers: Sequence[Callable[[Env], Wrapper]] | None = None,
**kwargs: Any,
) VectorEnv

Create a vector environment according to the given ID.

Note

This feature is experimental, and is likely to change in future releases.

gymnasium.envs.registration.EnvCreator(**kwargs: Any) Env

The call signature of entry points accepted by register(). This is used merely for type annotations.

gymnasium.envs.registration.VectorEnvCreator(**kwargs: Any) VectorEnv

The call signature of vector entry points accepted by register(). This is used merely for type annotations.

class gymnasium.envs.registration.WrapperSpec(name: str, entry_point: str, kwargs: dict[str, Any] | None)

Bases: object

A specification for recording wrapper configs.

  • name: The name of the wrapper.

  • entry_point: The location of the wrapper to create from.

  • kwargs: Additional keyword arguments passed to the wrapper. If the wrapper doesn’t inherit from EzPickle then this is None