Merge branch 'pypi-package' into future

This commit is contained in:
Dominik Moritz Roth 2023-10-29 14:23:31 +01:00
commit 765d4d495f
9 changed files with 290 additions and 77 deletions

40
.github/workflows/publish-to-pypi.yml vendored Normal file
View File

@ -0,0 +1,40 @@
name: Publish Python package to PyPI
on:
# Action currently disabled to only push to TestPyPI for now
#push:
# tags:
# - '*'
jobs:
publish:
name: Publish to PyPI
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/') # Only run on tagged commits
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Install pypa/build/setuptools/twine
run: >-
python3 -m
pip install
build setuptools twine
--user
- name: Build a binary wheel and a source tarball
run: python3 -m build
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: twine upload dist/*

View File

@ -0,0 +1,38 @@
name: Publish Python package to TestPyPI
on:
push:
tags:
- '*'
jobs:
publish:
name: Publish to TestPyPI
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/') # Only run on tagged commits
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Install pypa/build/setuptools/twine
run: >-
python3 -m
pip install
build setuptools twine
--user
- name: Build a binary wheel and a source tarball
run: python3 -m build
- name: Publish to TestPyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_TOKEN }}
run: twine upload --repository-url https://test.pypi.org/legacy/ dist/*

14
MANIFEST.in Normal file
View File

@ -0,0 +1,14 @@
# Include the README
include README.md
# Include the license, Code of Conduct and Contributing guidelines
include LICENSE
include CODE_OF_CONDUCT.md
include CONTRIBUTING.md
# Include stl and xml files from the fancy_gym/envs/mujoco directory
recursive-include fancy_gym/envs/mujoco *.stl
recursive-include fancy_gym/envs/mujoco *.xml
# Also shipping the most important part of fancy gym
include icon.svg

View File

@ -1,12 +1,12 @@
<h1 align="center"> <h1 align="center">
<br> <br>
<img src='./icon.svg' width="250px"> <img src='https://raw.githubusercontent.com/ALRhub/fancy_gym/master/icon.svg' width="250px">
<br><br> <br><br>
<b>Fancy Gym</b> <b>Fancy Gym</b>
<br><br> <br><br>
</h1> </h1>
| :exclamation: Fancy Gym has recently received a major refactor, which also updated many of the used dependencies to current versions. The update has brought some breaking changes. If you want to access the old version, check out the [legacy branch](https://github.com/ALRhub/fancy_gym/tree/legacy). Find out more about what changed [here](https://github.com/ALRhub/fancy_gym/pull/75). | | &#x2757; Fancy Gym has recently received a major refactor, which also updated many of the used dependencies to current versions. The update has brought some breaking changes. If you want to access the old version, check out the [legacy branch](https://github.com/ALRhub/fancy_gym/tree/legacy). Find out more about what changed [here](https://github.com/ALRhub/fancy_gym/pull/75). |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Built upon the foundation of [Gymnasium](https://gymnasium.farama.org/) (a maintained fork of OpenAIs renowned Gym library) `fancy_gym` offers a comprehensive collection of reinforcement learning environments. Built upon the foundation of [Gymnasium](https://gymnasium.farama.org/) (a maintained fork of OpenAIs renowned Gym library) `fancy_gym` offers a comprehensive collection of reinforcement learning environments.
@ -33,29 +33,61 @@ While the overarching objective of MP environments remains the learning of an op
## Installation ## Installation
1. Clone the repository We recommend installing `fancy_gym` into a virtual environments like [venv](https://docs.python.org/3/library/venv.html). 3rd party alternatives to venv like [Poetry](https://python-poetry.org/) or [Conda](https://docs.conda.io/en/latest/) can also be used.
### Installation from PyPI (recommended)
Install `fancy_gym` via
```bash ```bash
git clone git@github.com:ALRhub/fancy_gym.git pip install fancy_gym
```
2. Go to the folder
```bash
cd fancy_gym
```
3. Install with
```bash
pip install -e .
``` ```
We have a few optional dependencies. If you also want to install those use We have a few optional dependencies. If you also want to install those use
```bash ```bash
pip install -e '.[all]' # to install all optional dependencies # to install all optional dependencies
pip install -e '.[dmc,metaworld,box2d,mujoco,mujoco-legacy,jax,testing]' # or choose only those you want pip install 'fancy_gym[all]'
# or choose only those you want
pip install 'fancy_gym[dmc,box2d,mujoco-legacy,jax,testing]'
```
Pip can not automatically install up-to-date versions of metaworld, since they are not avaible on PyPI yet.
Install metaworld via
```bash
pip install metaworld@git+https://github.com/Farama-Foundation/Metaworld.git@d155d0051630bb365ea6a824e02c66c068947439#egg=metaworld
```
### Installation from master
1. Clone the repository
```bash
git clone git@github.com:ALRhub/fancy_gym.git
```
2. Go to the folder
```bash
cd fancy_gym
```
3. Install with
```bash
pip install -e .
```
We have a few optional dependencies. If you also want to install those use
```bash
# to install all optional dependencies
pip install -e '.[all]'
# or choose only those you want
pip install -e '.[dmc,box2d,mujoco-legacy,jax,testing]'
```
Metaworld has to be installed manually with
```bash
pip install metaworld@git+https://github.com/Farama-Foundation/Metaworld.git@d155d0051630bb365ea6a824e02c66c068947439#egg=metaworld
``` ```
## How to use Fancy Gym ## How to use Fancy Gym
@ -66,7 +98,7 @@ We will only show the basics here and prepared [multiple examples](fancy_gym/exa
Regular step based environments added by Fancy Gym are added into the `fancy/` namespace. Regular step based environments added by Fancy Gym are added into the `fancy/` namespace.
| :exclamation: Legacy versions of Fancy Gym used `fancy_gym.make(...)`. This is no longer supported and will raise an Exception on new versions. | | &#x2757; Legacy versions of Fancy Gym used `fancy_gym.make(...)`. This is no longer supported and will raise an Exception on new versions. |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | | ----------------------------------------------------------------------------------------------------------------------------------------------- |
```python ```python

View File

@ -6,7 +6,10 @@ from .envs.registry import ALL_MOVEMENT_PRIMITIVE_ENVIRONMENTS, MOVEMENT_PRIMITI
ALL_DMC_MOVEMENT_PRIMITIVE_ENVIRONMENTS = MOVEMENT_PRIMITIVE_ENVIRONMENTS_FOR_NS['dm_control'] ALL_DMC_MOVEMENT_PRIMITIVE_ENVIRONMENTS = MOVEMENT_PRIMITIVE_ENVIRONMENTS_FOR_NS['dm_control']
ALL_FANCY_MOVEMENT_PRIMITIVE_ENVIRONMENTS = MOVEMENT_PRIMITIVE_ENVIRONMENTS_FOR_NS['fancy'] ALL_FANCY_MOVEMENT_PRIMITIVE_ENVIRONMENTS = MOVEMENT_PRIMITIVE_ENVIRONMENTS_FOR_NS['fancy']
ALL_METAWORLD_MOVEMENT_PRIMITIVE_ENVIRONMENTS = MOVEMENT_PRIMITIVE_ENVIRONMENTS_FOR_NS['metaworld'] if 'metaworld' in MOVEMENT_PRIMITIVE_ENVIRONMENTS_FOR_NS:
ALL_METAWORLD_MOVEMENT_PRIMITIVE_ENVIRONMENTS = MOVEMENT_PRIMITIVE_ENVIRONMENTS_FOR_NS['metaworld']
else:
ALL_METAWORLD_MOVEMENT_PRIMITIVE_ENVIRONMENTS = 'Metaworld is not installed.'
ALL_GYM_MOVEMENT_PRIMITIVE_ENVIRONMENTS = MOVEMENT_PRIMITIVE_ENVIRONMENTS_FOR_NS['gym'] ALL_GYM_MOVEMENT_PRIMITIVE_ENVIRONMENTS = MOVEMENT_PRIMITIVE_ENVIRONMENTS_FOR_NS['gym']

View File

@ -7,56 +7,63 @@ from ..envs.registry import register
from . import goal_object_change_mp_wrapper, goal_change_mp_wrapper, goal_endeffector_change_mp_wrapper, \ from . import goal_object_change_mp_wrapper, goal_change_mp_wrapper, goal_endeffector_change_mp_wrapper, \
object_change_mp_wrapper object_change_mp_wrapper
from . import metaworld_adapter try:
import metaworld
except ModuleNotFoundError:
print('[FANCY GYM] Metaworld not avaible.')
else:
# Will only get executed, if import succeeds
metaworld_adapter.register_all_ML1() from . import metaworld_adapter
ALL_METAWORLD_MOVEMENT_PRIMITIVE_ENVIRONMENTS = {"DMP": [], "ProMP": [], "ProDMP": []} metaworld_adapter.register_all_ML1()
# MetaWorld ALL_METAWORLD_MOVEMENT_PRIMITIVE_ENVIRONMENTS = {"DMP": [], "ProMP": [], "ProDMP": []}
_goal_change_envs = ["assembly-v2", "pick-out-of-hole-v2", "plate-slide-v2", "plate-slide-back-v2",
"plate-slide-side-v2", "plate-slide-back-side-v2"]
for _task in _goal_change_envs:
register(
id=f'metaworld/{_task}',
register_step_based=False,
mp_wrapper=goal_change_mp_wrapper.MPWrapper,
add_mp_types=['ProMP', 'ProDMP'],
)
_object_change_envs = ["bin-picking-v2", "hammer-v2", "sweep-into-v2"] # MetaWorld
for _task in _object_change_envs: _goal_change_envs = ["assembly-v2", "pick-out-of-hole-v2", "plate-slide-v2", "plate-slide-back-v2",
register( "plate-slide-side-v2", "plate-slide-back-side-v2"]
id=f'metaworld/{_task}', for _task in _goal_change_envs:
register_step_based=False, register(
mp_wrapper=object_change_mp_wrapper.MPWrapper, id=f'metaworld/{_task}',
add_mp_types=['ProMP', 'ProDMP'], register_step_based=False,
) mp_wrapper=goal_change_mp_wrapper.MPWrapper,
add_mp_types=['ProMP', 'ProDMP'],
)
_goal_and_object_change_envs = ["box-close-v2", "button-press-v2", "button-press-wall-v2", "button-press-topdown-v2", _object_change_envs = ["bin-picking-v2", "hammer-v2", "sweep-into-v2"]
"button-press-topdown-wall-v2", "coffee-button-v2", "coffee-pull-v2", for _task in _object_change_envs:
"coffee-push-v2", "dial-turn-v2", "disassemble-v2", "door-close-v2", register(
"door-lock-v2", "door-open-v2", "door-unlock-v2", "hand-insert-v2", id=f'metaworld/{_task}',
"drawer-close-v2", "drawer-open-v2", "faucet-open-v2", "faucet-close-v2", register_step_based=False,
"handle-press-side-v2", "handle-press-v2", "handle-pull-side-v2", mp_wrapper=object_change_mp_wrapper.MPWrapper,
"handle-pull-v2", "lever-pull-v2", "peg-insert-side-v2", "pick-place-wall-v2", add_mp_types=['ProMP', 'ProDMP'],
"reach-v2", "push-back-v2", "push-v2", "pick-place-v2", "peg-unplug-side-v2", )
"soccer-v2", "stick-push-v2", "stick-pull-v2", "push-wall-v2", "reach-wall-v2",
"shelf-place-v2", "sweep-v2", "window-open-v2", "window-close-v2"
]
for _task in _goal_and_object_change_envs:
register(
id=f'metaworld/{_task}',
register_step_based=False,
mp_wrapper=goal_object_change_mp_wrapper.MPWrapper,
add_mp_types=['ProMP', 'ProDMP'],
)
_goal_and_endeffector_change_envs = ["basketball-v2"] _goal_and_object_change_envs = ["box-close-v2", "button-press-v2", "button-press-wall-v2", "button-press-topdown-v2",
for _task in _goal_and_endeffector_change_envs: "button-press-topdown-wall-v2", "coffee-button-v2", "coffee-pull-v2",
register( "coffee-push-v2", "dial-turn-v2", "disassemble-v2", "door-close-v2",
id=f'metaworld/{_task}', "door-lock-v2", "door-open-v2", "door-unlock-v2", "hand-insert-v2",
register_step_based=False, "drawer-close-v2", "drawer-open-v2", "faucet-open-v2", "faucet-close-v2",
mp_wrapper=goal_endeffector_change_mp_wrapper.MPWrapper, "handle-press-side-v2", "handle-press-v2", "handle-pull-side-v2",
add_mp_types=['ProMP', 'ProDMP'], "handle-pull-v2", "lever-pull-v2", "peg-insert-side-v2", "pick-place-wall-v2",
) "reach-v2", "push-back-v2", "push-v2", "pick-place-v2", "peg-unplug-side-v2",
"soccer-v2", "stick-push-v2", "stick-pull-v2", "push-wall-v2", "reach-wall-v2",
"shelf-place-v2", "sweep-v2", "window-open-v2", "window-close-v2"
]
for _task in _goal_and_object_change_envs:
register(
id=f'metaworld/{_task}',
register_step_based=False,
mp_wrapper=goal_object_change_mp_wrapper.MPWrapper,
add_mp_types=['ProMP', 'ProDMP'],
)
_goal_and_endeffector_change_envs = ["basketball-v2"]
for _task in _goal_and_endeffector_change_envs:
register(
id=f'metaworld/{_task}',
register_step_based=False,
mp_wrapper=goal_endeffector_change_mp_wrapper.MPWrapper,
add_mp_types=['ProMP', 'ProDMP'],
)

View File

@ -11,11 +11,7 @@ import numpy as np
from fancy_gym.utils.env_compatibility import EnvCompatibility from fancy_gym.utils.env_compatibility import EnvCompatibility
try: import metaworld
import metaworld
except Exception:
print('[FANCY GYM] Metaworld not avaible')
class FixMetaworldHasIncorrectObsSpaceWrapper(gym.Wrapper, gym.utils.RecordConstructorArgs): class FixMetaworldHasIncorrectObsSpaceWrapper(gym.Wrapper, gym.utils.RecordConstructorArgs):
def __init__(self, env: gym.Env): def __init__(self, env: gym.Env):

79
pyproject.toml Normal file
View File

@ -0,0 +1,79 @@
[project]
name = "fancy_gym"
version = "0.1.0"
description = "Fancy Gym: Unifying interface for various RL benchmarks with support for Black Box approaches."
readme = "README.md"
authors = [
{name = "Fabian Otto", email = "fabian.otto@uni-tuebingen.de"},
{name = "Onur Celik", email = "celik@kit.edu"},
{name = "Dominik Roth", email = "fancy_gym@dominik-roth.eu"},
{name = "Hongyi Zhou", email = "hongyi.zhou@kit.edu"}
]
license = { text = "MIT License" }
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Operating System :: OS Independent",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11"
]
dependencies = [
"mp_pytorch<=0.1.3",
"mujoco==2.3.3",
"gymnasium[mujoco]>=0.26.0"
]
requires-python = ">=3.7"
[project.urls]
"Homepage" = "https://github.com/ALRhub/fancy_gym/"
#"Documentation" = "https://github.com/ALRhub/fancy_gym/"
"Bug Tracker" = "https://github.com/ALRhub/fancy_gym/issues"
#"Repository" = "https://github.com/ALRhub/fancy_gym/"
[build-system]
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"
[project.optional-dependencies]
dmc = ["shimmy[dm-control]", "Shimmy==1.0.0"]
# PyPi does not allow external dependencies. Metaworld will have to be installed manually until Farama publishes up-to-date version of metaworld on PyPi.
#metaworld = ["metaworld @ git+https://github.com/Farama-Foundation/Metaworld.git@d155d0051630bb365ea6a824e02c66c068947439#egg=metaworld"]
box2d = ["gymnasium[box2d]>=0.26.0"]
mujoco-legacy = ["mujoco-py>=2.1,<2.2", "cython<3"]
jax = ["jax>=0.4.0", "jaxlib>=0.4.0"]
all = [
# include all the optional dependencies
"shimmy[dm-control]",
"Shimmy==1.0.0",
#"metaworld @ git+https://github.com/Farama-Foundation/Metaworld.git@d155d0051630bb365ea6a824e02c66c068947439#egg=metaworld",
"mujoco==2.3.3",
"gymnasium[box2d,mujoco]>=0.26.0",
"mujoco-py>=2.1,<2.2",
"cython<3",
"jax>=0.4.0",
"jaxlib>=0.4.0"
]
testing = [
"pytest",
# include all the optional dependencies as well
"shimmy[dm-control]",
"Shimmy==1.0.0",
#"metaworld @ git+https://github.com/Farama-Foundation/Metaworld.git@d155d0051630bb365ea6a824e02c66c068947439#egg=metaworld",
"mujoco==2.3.3",
"gymnasium[box2d,mujoco]>=0.26.0",
"mujoco-py>=2.1,<2.2",
"cython<3",
"jax>=0.4.0",
"jaxlib>=0.4.0"
]

View File

@ -1,15 +1,17 @@
# We still provide a setup.py for backwards compatability.
# But the pyproject.toml should be prefered.
import itertools import itertools
from pathlib import Path from pathlib import Path
from typing import List from typing import List
from setuptools import setup, find_packages from setuptools import setup, find_packages
print('[!] You are currently installing/building fancy_gym via setup.py. This is only provided for backwards-compatability. Please use the pyproject.toml instead.')
# Environment-specific dependencies for dmc and metaworld # Environment-specific dependencies for dmc and metaworld
extras = { extras = {
'dmc': ['shimmy[dm-control]', 'Shimmy==1.0.0'], 'dmc': ['shimmy[dm-control]', 'Shimmy==1.0.0'],
'metaworld': ['metaworld @ git+https://github.com/Farama-Foundation/Metaworld.git@d155d0051630bb365ea6a824e02c66c068947439#egg=metaworld'],
'box2d': ['gymnasium[box2d]>=0.26.0'], 'box2d': ['gymnasium[box2d]>=0.26.0'],
'mujoco': ['mujoco==2.3.3', 'gymnasium[mujoco]>0.26.0'],
'mujoco-legacy': ['mujoco-py >=2.1,<2.2', 'cython<3'], 'mujoco-legacy': ['mujoco-py >=2.1,<2.2', 'cython<3'],
'jax': ["jax >=0.4.0", "jaxlib >=0.4.0"], 'jax': ["jax >=0.4.0", "jaxlib >=0.4.0"],
} }
@ -35,7 +37,7 @@ def find_package_data(extensions_to_include: List[str]) -> List[str]:
setup( setup(
author='Fabian Otto, Onur Celik, Dominik Roth, Hongyi Zhou', author='Fabian Otto, Onur Celik, Dominik Roth, Hongyi Zhou',
name='fancy_gym', name='fancy_gym',
version='1.0', version='0.1.0',
classifiers=[ classifiers=[
'Development Status :: 4 - Beta', 'Development Status :: 4 - Beta',
'Intended Audience :: Science/Research', 'Intended Audience :: Science/Research',
@ -48,11 +50,13 @@ setup(
'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
], ],
extras_require=extras, extras_require=extras,
install_requires=[ install_requires=[
'gymnasium>=0.26.0', 'mp_pytorch<=0.1.3',
'mp_pytorch<=0.1.3' 'mujoco==2.3.3',
'gymnasium[mujoco]>=0.26.0'
], ],
packages=[package for package in find_packages( packages=[package for package in find_packages(
) if package.startswith("fancy_gym")], ) if package.startswith("fancy_gym")],