- Install miniconda3.
- (Optional, but recommended) If you are using a conda version
<=23.9.0
, set the conda solver to libmamba for faster dependency solving. Starting from conda version23.10.0
, libmamba is the default solver.conda config --set solver libmamba
- Clone the SustainGym repo, and enter the
sustaingym
directory.git clone https://github.com/chrisyeh96/sustaingym.git cd sustaingym
- Create conda environment. Replace
XX
below with the name of the SustainGym environment you want to work on. By default, theenv_XX.yml
environment files assume that you have a NVIDIA GPU. If you do not have a NVIDIA GPU, you may need to modify theenv_XX.yml
file.conda env update --file env_XX.yml --prune
- Make code modifications in a separate git branch
git checkout -b new_feature
- From repo root folder, run mypy type checker and fix any errors.
mypy sustaingym
- From repo root folder, run code linter and fix any linting errors.
flake8 sustaingym
- Commit changes in git and push.
- Submit pull request on GitHub.
First, set your terminal directory to this repo's root directory. Next, make sure you have activated the appropriate conda environment for the SustainGym environment you want to test (e.g., conda activate sustaingym_ev
). Finally, run the unit tests for the desired SustainGym environment:
python -m unittest -v tests/test_evcharging.py
First, increment the version number in pyproject.toml. Then, follow these commands:
# create a conda environment with appropriate build tools
conda env update --file env_build.yml --prune
conda activate build
# remove generated pkl files from CogenEnv
rm sustaingym/data/cogen/ambients_data/*.pkl
# clean cached build files
rm -r sustaingym.egg-info
rm -r dist
# build source dist (.sdist) and wheel (.whl) files
python -m build
# upload built files to PyPI
twine upload --repository testpypi dist/* # for testpypi
twine upload dist/*
# create a new tag
git tag vX.Y.Z
git push origin --tags
The SustainGym website and documentation is written in the docs/
folder and built using Sphinx. The API reference documentation is automatically generated from class and function docstrings. See the section coding style guide below for details.
We use the following Sphinx extensions to build our documentation site:
MyST Parser (myst_parser)
: allows using Markdown files instead of ReStructuredText files. See the MyST Roles and Directives documentation for instructions on how to use Sphinx directives in Markdown files.- Even though we use Markdown for the documentation files, Python docstrings in SustainGym code still must use ReStructuredText syntax for formatting.
- Sphinx AutoAPI (
autoapi.extension
): automatically generates API documentation based on Python docstrings. Unlikesphinx.ext.autosummary
, Sphinx AutoAPI uses static code analysis without needing to import Python code to read the docstrings. This is important for SustainGym because the different environments within SustainGym are allowed to have conflicting dependencies.- Unfortunately, Sphinx AutoAPI does not properly handle namespace packages yet. See this GitHub issue. This is why have
__init__.py
files in every directory in the SustainGym codebase, even though many of these files are empty.
- Unfortunately, Sphinx AutoAPI does not properly handle namespace packages yet. See this GitHub issue. This is why have
sphinx.ext.napoleon
: allows using Google-style docstrings for documenting functions.- By default, the this extension does not let us easily document functions that return multiple variables at once (i.e., a tuple return type). Following this StackOverflow response, we choose to use the same documentation format for function arguments and return values by using the following line in our Sphinx configuration at
docs/conf.py
.
napoleon_custom_sections = [("Returns", "params_style")]
- By default, the this extension does not let us easily document functions that return multiple variables at once (i.e., a tuple return type). Following this StackOverflow response, we choose to use the same documentation format for function arguments and return values by using the following line in our Sphinx configuration at
- Furo theme
An example of the required coding style is shown below. It is based on the Google Python style guide. Several points deserve elaboration:
- The arguments of a class's
__init__()
function should be documented in the class docstring, instead of the__init__()
function docstring. Only use the__init__()
function docstring to document any implementation details. This is because Sphinx AutoAPI does not explicitly document the__init__()
function. - In a class docstring, class attributes should be documented with type information.
- In a function docstring, function arguments do not need to be documented with type information as long as appropriate type annotations are provided in the function signature.
- In a function docstring, function return values should be documented just like arguments.
"""This module implements MyClass."""
class MyClass:
"""Short description of class.
Longer description of class.
Can be multi-line.
Args:
option: str, description of option
Attributes:
first_line: str, first line that gets printed
num_prints: int, number of times that print() has been called. When
description is long, indent the subsequent lines.
Example::
my_obj = MyClass(option='hello')
text, num_prints = my_obj.print(name='John')
"""
def __init__(self, option: str):
self.first_line = option + ' world!'
self.num_prints = 0
def print(self, name: str) -> tuple[str, int]:
"""Prints two lines and returns the printed string.
Args:
name: str, name that gets printed
Returns:
text: text that was printed
num_prints: number of times that print() has been called
"""
text = f'{self.instance_var}\nMy name is {name}!'
self.num_prints += 1
print(text)
return text, self.num_prints
To build the website, you can follow these steps either locally on your computer or in a GitHub Codespace.
-
If you are installing dependencies locally, I recommend first creating a conda environment by running the following commands from the repo root folder. If you are using a GitHub Codespace, skip this step.
# create a new conda environment named "docs", and activate it conda create -n docs python=3.11 pip conda activate docs
-
Install the necessary dependencies from
docs/requirements.txt
. From thedocs/
folder:# install dependencies needed to build website locally pip install -r requirements.txt
-
Clear out the
docs/_build
directory if it exists, including any hidden folders or files (i.e., dotfiles). This isn't always necessary, but at a minimum, do this every time you changedocs/conf.py
. From thedocs/
folder:rm -r _build/* _build/.*
-
Build the documentation using Sphinx. From the
docs/
folder:sphinx-build -b html . _build
-
Launch a server to view the docs. From the
docs/_build
folder:python -m http.server
Optionally, change the port:
python -m http.server <port>
The SustainGym repo automatically compiles and deploys the website from the main
branch's docs/
folder to GitHub Pages whenever the main
branch is pushed to. This process can also be triggered manually from the "Build documentation" workflow in the Actions tab. The GitHub workflow configuration can be found at .github/workflows/build_docs.yml.