gen_env_docs.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. from __future__ import annotations
  2. import os
  3. import re
  4. from itertools import chain
  5. from gymnasium.envs.registration import registry
  6. from tqdm import tqdm
  7. from utils import env_name_format, trim
  8. readme_path = os.path.join(
  9. os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
  10. "README.md",
  11. )
  12. all_envs = list(registry.values())
  13. filtered_envs_by_type = {}
  14. env_names = []
  15. babyai_envs = {}
  16. wfc_envs = {}
  17. # Obtain filtered list
  18. for env_spec in tqdm(all_envs):
  19. if isinstance(env_spec.entry_point, str):
  20. # minigrid.envs:Env
  21. split = env_spec.entry_point.split(".")
  22. # ignore gymnasium.envs.env_type:Env
  23. env_module = split[0]
  24. if len(split) > 2 and "babyai" in split[2]:
  25. curr_babyai_env = split[2]
  26. babyai_env_name = curr_babyai_env.split(":")[1]
  27. babyai_envs[babyai_env_name] = env_spec
  28. elif len(split) > 2 and "wfc" in split[2]:
  29. curr_wfc_env = env_spec.kwargs["wfc_config"]
  30. wfc_envs[curr_wfc_env] = env_spec
  31. elif env_module == "minigrid":
  32. env_name = split[1]
  33. filtered_envs_by_type[env_name] = env_spec
  34. # if env_module != "minigrid":
  35. else:
  36. continue
  37. filtered_envs = {
  38. env[0]: env[1]
  39. for env in sorted(
  40. filtered_envs_by_type.items(),
  41. key=lambda item: item[1].entry_point.split(".")[1],
  42. )
  43. }
  44. filtered_babyai_envs = {
  45. env[0]: env[1]
  46. for env in sorted(
  47. babyai_envs.items(),
  48. key=lambda item: item[1].entry_point.split(".")[1],
  49. )
  50. }
  51. # Because they share a class, only the default (MazeSimple) environment should be kept
  52. canonical_wfc_env_name = "MazeSimple"
  53. filtered_wfc_envs = {canonical_wfc_env_name: wfc_envs[canonical_wfc_env_name]}
  54. for env_name, env_spec in chain(
  55. filtered_envs.items(), filtered_babyai_envs.items(), filtered_wfc_envs.items()
  56. ):
  57. env = env_spec.make()
  58. docstring = trim(env.unwrapped.__doc__)
  59. # minigrid.envs:Env or minigrid.envs.babyai:Env
  60. split = env_spec.entry_point.split(".")
  61. # ignore minigrid.envs.env_type:Env
  62. env_module = split[0]
  63. env_name = split[-1].split(":")[-1]
  64. env_type = env_module if len(split) == 2 else split[-1].split(":")[0]
  65. path_name = ""
  66. os.makedirs(
  67. os.path.join(
  68. os.path.dirname(os.path.dirname(__file__)), "environments", env_type
  69. ),
  70. exist_ok=True,
  71. )
  72. v_path = os.path.join(
  73. os.path.dirname(os.path.dirname(__file__)),
  74. "environments",
  75. env_type,
  76. f"{env_name}.md",
  77. )
  78. formatted_env_name = env_name_format(env_name)
  79. # Front matter
  80. front_matter = f"""---
  81. autogenerated:
  82. title: {formatted_env_name}
  83. ---
  84. """
  85. # Title and gif
  86. title = f"# {formatted_env_name}"
  87. gif = (
  88. "```{figure} "
  89. + f"""/_static/videos/{env_type}/{env_name}.gif
  90. :alt: {formatted_env_name}
  91. :width: 200px
  92. ```
  93. """
  94. )
  95. # Environment attributes
  96. action_space_table = env.action_space.__repr__().replace("\n", "")
  97. observation_space_table = env.observation_space.__repr__().replace("\n", "")
  98. env_attributes = f"""
  99. | | |
  100. |---|---|
  101. | Action Space | `{re.sub(' +', ' ', action_space_table)}` |
  102. | Observation Space | `{re.sub(' +', ' ', observation_space_table)}` |
  103. | Reward Range | `{env.reward_range}` |
  104. | Creation | `gymnasium.make("{env_spec.id}")` |
  105. """
  106. # Create Markdown file content
  107. if docstring is None:
  108. docstring = "No information provided"
  109. all_text = f"""{front_matter}
  110. {title}
  111. {gif}
  112. {env_attributes}
  113. {docstring}
  114. """
  115. file = open(v_path, "w+", encoding="utf-8")
  116. file.write(all_text)
  117. file.close()