kaggle-environments 0.2.0__py3-none-any.whl → 1.20.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kaggle-environments might be problematic. Click here for more details.

Files changed (215) hide show
  1. kaggle_environments/__init__.py +49 -13
  2. kaggle_environments/agent.py +177 -124
  3. kaggle_environments/api.py +31 -0
  4. kaggle_environments/core.py +298 -173
  5. kaggle_environments/envs/cabt/cabt.js +164 -0
  6. kaggle_environments/envs/cabt/cabt.json +28 -0
  7. kaggle_environments/envs/cabt/cabt.py +186 -0
  8. kaggle_environments/envs/cabt/cg/__init__.py +0 -0
  9. kaggle_environments/envs/cabt/cg/cg.dll +0 -0
  10. kaggle_environments/envs/cabt/cg/game.py +75 -0
  11. kaggle_environments/envs/cabt/cg/libcg.so +0 -0
  12. kaggle_environments/envs/cabt/cg/sim.py +48 -0
  13. kaggle_environments/envs/cabt/test_cabt.py +120 -0
  14. kaggle_environments/envs/chess/chess.js +4289 -0
  15. kaggle_environments/envs/chess/chess.json +60 -0
  16. kaggle_environments/envs/chess/chess.py +4241 -0
  17. kaggle_environments/envs/chess/test_chess.py +60 -0
  18. kaggle_environments/envs/connectx/connectx.ipynb +3186 -0
  19. kaggle_environments/envs/connectx/connectx.js +1 -1
  20. kaggle_environments/envs/connectx/connectx.json +15 -1
  21. kaggle_environments/envs/connectx/connectx.py +6 -23
  22. kaggle_environments/envs/connectx/test_connectx.py +70 -24
  23. kaggle_environments/envs/football/football.ipynb +75 -0
  24. kaggle_environments/envs/football/football.json +91 -0
  25. kaggle_environments/envs/football/football.py +277 -0
  26. kaggle_environments/envs/football/helpers.py +95 -0
  27. kaggle_environments/envs/football/test_football.py +360 -0
  28. kaggle_environments/envs/halite/__init__.py +0 -0
  29. kaggle_environments/envs/halite/halite.ipynb +44741 -0
  30. kaggle_environments/envs/halite/halite.js +199 -83
  31. kaggle_environments/envs/halite/halite.json +31 -18
  32. kaggle_environments/envs/halite/halite.py +164 -303
  33. kaggle_environments/envs/halite/helpers.py +720 -0
  34. kaggle_environments/envs/halite/test_halite.py +190 -0
  35. kaggle_environments/envs/hungry_geese/__init__.py +0 -0
  36. kaggle_environments/envs/{battlegeese/battlegeese.js → hungry_geese/hungry_geese.js} +38 -22
  37. kaggle_environments/envs/{battlegeese/battlegeese.json → hungry_geese/hungry_geese.json} +22 -15
  38. kaggle_environments/envs/hungry_geese/hungry_geese.py +316 -0
  39. kaggle_environments/envs/hungry_geese/test_hungry_geese.py +0 -0
  40. kaggle_environments/envs/identity/identity.json +6 -5
  41. kaggle_environments/envs/identity/identity.py +15 -2
  42. kaggle_environments/envs/kore_fleets/__init__.py +0 -0
  43. kaggle_environments/envs/kore_fleets/helpers.py +1005 -0
  44. kaggle_environments/envs/kore_fleets/kore_fleets.ipynb +114 -0
  45. kaggle_environments/envs/kore_fleets/kore_fleets.js +658 -0
  46. kaggle_environments/envs/kore_fleets/kore_fleets.json +164 -0
  47. kaggle_environments/envs/kore_fleets/kore_fleets.py +555 -0
  48. kaggle_environments/envs/kore_fleets/starter_bots/java/Bot.java +54 -0
  49. kaggle_environments/envs/kore_fleets/starter_bots/java/README.md +26 -0
  50. kaggle_environments/envs/kore_fleets/starter_bots/java/jars/hamcrest-core-1.3.jar +0 -0
  51. kaggle_environments/envs/kore_fleets/starter_bots/java/jars/junit-4.13.2.jar +0 -0
  52. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Board.java +518 -0
  53. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Cell.java +61 -0
  54. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Configuration.java +24 -0
  55. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Direction.java +166 -0
  56. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Fleet.java +72 -0
  57. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/KoreJson.java +97 -0
  58. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Observation.java +72 -0
  59. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Pair.java +13 -0
  60. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Player.java +68 -0
  61. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Point.java +65 -0
  62. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/Shipyard.java +70 -0
  63. kaggle_environments/envs/kore_fleets/starter_bots/java/kore/ShipyardAction.java +59 -0
  64. kaggle_environments/envs/kore_fleets/starter_bots/java/main.py +73 -0
  65. kaggle_environments/envs/kore_fleets/starter_bots/java/test/BoardTest.java +567 -0
  66. kaggle_environments/envs/kore_fleets/starter_bots/java/test/ConfigurationTest.java +25 -0
  67. kaggle_environments/envs/kore_fleets/starter_bots/java/test/KoreJsonTest.java +62 -0
  68. kaggle_environments/envs/kore_fleets/starter_bots/java/test/ObservationTest.java +46 -0
  69. kaggle_environments/envs/kore_fleets/starter_bots/java/test/PointTest.java +21 -0
  70. kaggle_environments/envs/kore_fleets/starter_bots/java/test/ShipyardTest.java +22 -0
  71. kaggle_environments/envs/kore_fleets/starter_bots/java/test/configuration.json +1 -0
  72. kaggle_environments/envs/kore_fleets/starter_bots/java/test/fullob.json +1 -0
  73. kaggle_environments/envs/kore_fleets/starter_bots/java/test/observation.json +1 -0
  74. kaggle_environments/envs/kore_fleets/starter_bots/python/__init__.py +0 -0
  75. kaggle_environments/envs/kore_fleets/starter_bots/python/main.py +27 -0
  76. kaggle_environments/envs/kore_fleets/starter_bots/ts/Bot.ts +34 -0
  77. kaggle_environments/envs/kore_fleets/starter_bots/ts/DoNothingBot.ts +12 -0
  78. kaggle_environments/envs/kore_fleets/starter_bots/ts/MinerBot.ts +62 -0
  79. kaggle_environments/envs/kore_fleets/starter_bots/ts/README.md +55 -0
  80. kaggle_environments/envs/kore_fleets/starter_bots/ts/interpreter.ts +402 -0
  81. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Board.ts +514 -0
  82. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Cell.ts +63 -0
  83. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Configuration.ts +25 -0
  84. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Direction.ts +169 -0
  85. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Fleet.ts +76 -0
  86. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/KoreIO.ts +70 -0
  87. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Observation.ts +45 -0
  88. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Pair.ts +11 -0
  89. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Player.ts +68 -0
  90. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Point.ts +65 -0
  91. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/Shipyard.ts +72 -0
  92. kaggle_environments/envs/kore_fleets/starter_bots/ts/kore/ShipyardAction.ts +58 -0
  93. kaggle_environments/envs/kore_fleets/starter_bots/ts/main.py +73 -0
  94. kaggle_environments/envs/kore_fleets/starter_bots/ts/miner.py +73 -0
  95. kaggle_environments/envs/kore_fleets/starter_bots/ts/package.json +23 -0
  96. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/BoardTest.ts +551 -0
  97. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ConfigurationTest.ts +16 -0
  98. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ObservationTest.ts +33 -0
  99. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/PointTest.ts +17 -0
  100. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/ShipyardTest.ts +18 -0
  101. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/configuration.json +1 -0
  102. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/fullob.json +1 -0
  103. kaggle_environments/envs/kore_fleets/starter_bots/ts/test/observation.json +1 -0
  104. kaggle_environments/envs/kore_fleets/starter_bots/ts/tsconfig.json +22 -0
  105. kaggle_environments/envs/kore_fleets/test_kore_fleets.py +331 -0
  106. kaggle_environments/envs/lux_ai_2021/README.md +3 -0
  107. kaggle_environments/envs/lux_ai_2021/__init__.py +0 -0
  108. kaggle_environments/envs/lux_ai_2021/agents.py +11 -0
  109. kaggle_environments/envs/lux_ai_2021/dimensions/754.js +2 -0
  110. kaggle_environments/envs/lux_ai_2021/dimensions/754.js.LICENSE.txt +296 -0
  111. kaggle_environments/envs/lux_ai_2021/dimensions/main.js +1 -0
  112. kaggle_environments/envs/lux_ai_2021/index.html +43 -0
  113. kaggle_environments/envs/lux_ai_2021/lux_ai_2021.json +100 -0
  114. kaggle_environments/envs/lux_ai_2021/lux_ai_2021.py +231 -0
  115. kaggle_environments/envs/lux_ai_2021/test_agents/__init__.py +0 -0
  116. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.js +6 -0
  117. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_constants.json +59 -0
  118. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/game_objects.js +145 -0
  119. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/io.js +14 -0
  120. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/kit.js +209 -0
  121. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/map.js +107 -0
  122. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/lux/parser.js +79 -0
  123. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.js +88 -0
  124. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/main.py +75 -0
  125. kaggle_environments/envs/lux_ai_2021/test_agents/js_simple/simple.tar.gz +0 -0
  126. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/__init__.py +0 -0
  127. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/annotate.py +20 -0
  128. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/constants.py +25 -0
  129. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game.py +86 -0
  130. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.json +59 -0
  131. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_constants.py +7 -0
  132. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_map.py +106 -0
  133. kaggle_environments/envs/lux_ai_2021/test_agents/python/lux/game_objects.py +154 -0
  134. kaggle_environments/envs/lux_ai_2021/test_agents/python/random_agent.py +38 -0
  135. kaggle_environments/envs/lux_ai_2021/test_agents/python/simple_agent.py +82 -0
  136. kaggle_environments/envs/lux_ai_2021/test_lux.py +19 -0
  137. kaggle_environments/envs/lux_ai_2021/testing.md +23 -0
  138. kaggle_environments/envs/lux_ai_2021/todo.md.og +18 -0
  139. kaggle_environments/envs/lux_ai_s3/README.md +21 -0
  140. kaggle_environments/envs/lux_ai_s3/agents.py +5 -0
  141. kaggle_environments/envs/lux_ai_s3/index.html +42 -0
  142. kaggle_environments/envs/lux_ai_s3/lux_ai_s3.json +47 -0
  143. kaggle_environments/envs/lux_ai_s3/lux_ai_s3.py +178 -0
  144. kaggle_environments/envs/lux_ai_s3/luxai_s3/__init__.py +1 -0
  145. kaggle_environments/envs/lux_ai_s3/luxai_s3/env.py +819 -0
  146. kaggle_environments/envs/lux_ai_s3/luxai_s3/globals.py +9 -0
  147. kaggle_environments/envs/lux_ai_s3/luxai_s3/params.py +101 -0
  148. kaggle_environments/envs/lux_ai_s3/luxai_s3/profiler.py +141 -0
  149. kaggle_environments/envs/lux_ai_s3/luxai_s3/pygame_render.py +222 -0
  150. kaggle_environments/envs/lux_ai_s3/luxai_s3/spaces.py +27 -0
  151. kaggle_environments/envs/lux_ai_s3/luxai_s3/state.py +464 -0
  152. kaggle_environments/envs/lux_ai_s3/luxai_s3/utils.py +12 -0
  153. kaggle_environments/envs/lux_ai_s3/luxai_s3/wrappers.py +156 -0
  154. kaggle_environments/envs/lux_ai_s3/test_agents/python/agent.py +78 -0
  155. kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/__init__.py +0 -0
  156. kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/kit.py +31 -0
  157. kaggle_environments/envs/lux_ai_s3/test_agents/python/lux/utils.py +17 -0
  158. kaggle_environments/envs/lux_ai_s3/test_agents/python/main.py +66 -0
  159. kaggle_environments/envs/lux_ai_s3/test_lux.py +9 -0
  160. kaggle_environments/envs/mab/__init__.py +0 -0
  161. kaggle_environments/envs/mab/agents.py +12 -0
  162. kaggle_environments/envs/mab/mab.js +100 -0
  163. kaggle_environments/envs/mab/mab.json +74 -0
  164. kaggle_environments/envs/mab/mab.py +146 -0
  165. kaggle_environments/envs/open_spiel/__init__.py +0 -0
  166. kaggle_environments/envs/open_spiel/games/__init__.py +0 -0
  167. kaggle_environments/envs/open_spiel/games/chess/chess.js +441 -0
  168. kaggle_environments/envs/open_spiel/games/chess/image_config.jsonl +20 -0
  169. kaggle_environments/envs/open_spiel/games/chess/openings.jsonl +20 -0
  170. kaggle_environments/envs/open_spiel/games/connect_four/__init__.py +0 -0
  171. kaggle_environments/envs/open_spiel/games/connect_four/connect_four.js +284 -0
  172. kaggle_environments/envs/open_spiel/games/connect_four/connect_four_proxy.py +86 -0
  173. kaggle_environments/envs/open_spiel/games/go/__init__.py +0 -0
  174. kaggle_environments/envs/open_spiel/games/go/go.js +481 -0
  175. kaggle_environments/envs/open_spiel/games/go/go_proxy.py +99 -0
  176. kaggle_environments/envs/open_spiel/games/tic_tac_toe/__init__.py +0 -0
  177. kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe.js +345 -0
  178. kaggle_environments/envs/open_spiel/games/tic_tac_toe/tic_tac_toe_proxy.py +98 -0
  179. kaggle_environments/envs/open_spiel/games/universal_poker/__init__.py +0 -0
  180. kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker.js +431 -0
  181. kaggle_environments/envs/open_spiel/games/universal_poker/universal_poker_proxy.py +159 -0
  182. kaggle_environments/envs/open_spiel/html_playthrough_generator.py +31 -0
  183. kaggle_environments/envs/open_spiel/observation.py +128 -0
  184. kaggle_environments/envs/open_spiel/open_spiel.py +565 -0
  185. kaggle_environments/envs/open_spiel/proxy.py +138 -0
  186. kaggle_environments/envs/open_spiel/test_open_spiel.py +191 -0
  187. kaggle_environments/envs/rps/__init__.py +0 -0
  188. kaggle_environments/envs/rps/agents.py +84 -0
  189. kaggle_environments/envs/rps/helpers.py +25 -0
  190. kaggle_environments/envs/rps/rps.js +117 -0
  191. kaggle_environments/envs/rps/rps.json +63 -0
  192. kaggle_environments/envs/rps/rps.py +90 -0
  193. kaggle_environments/envs/rps/test_rps.py +110 -0
  194. kaggle_environments/envs/rps/utils.py +7 -0
  195. kaggle_environments/envs/tictactoe/test_tictactoe.py +43 -77
  196. kaggle_environments/envs/tictactoe/tictactoe.ipynb +1397 -0
  197. kaggle_environments/envs/tictactoe/tictactoe.json +10 -2
  198. kaggle_environments/envs/tictactoe/tictactoe.py +1 -1
  199. kaggle_environments/errors.py +2 -4
  200. kaggle_environments/helpers.py +377 -0
  201. kaggle_environments/main.py +214 -50
  202. kaggle_environments/schemas.json +23 -18
  203. kaggle_environments/static/player.html +206 -74
  204. kaggle_environments/utils.py +46 -73
  205. kaggle_environments-1.20.0.dist-info/METADATA +25 -0
  206. kaggle_environments-1.20.0.dist-info/RECORD +211 -0
  207. {kaggle_environments-0.2.0.dist-info → kaggle_environments-1.20.0.dist-info}/WHEEL +1 -2
  208. kaggle_environments-1.20.0.dist-info/entry_points.txt +3 -0
  209. kaggle_environments/envs/battlegeese/battlegeese.py +0 -219
  210. kaggle_environments/temp.py +0 -14
  211. kaggle_environments-0.2.0.dist-info/METADATA +0 -393
  212. kaggle_environments-0.2.0.dist-info/RECORD +0 -33
  213. kaggle_environments-0.2.0.dist-info/entry_points.txt +0 -3
  214. kaggle_environments-0.2.0.dist-info/top_level.txt +0 -1
  215. {kaggle_environments-0.2.0.dist-info → kaggle_environments-1.20.0.dist-info/licenses}/LICENSE +0 -0
@@ -15,50 +15,84 @@
15
15
  import argparse
16
16
  import json
17
17
  import traceback
18
- from kaggle_environments import environments, evaluate, make, utils
18
+ from logging.config import dictConfig
19
+ from typing import Optional
19
20
 
21
+ from . import errors, utils
22
+ from .agent import Agent
23
+ from .core import environments, evaluate, make
20
24
 
21
25
  parser = argparse.ArgumentParser(description="Kaggle Simulations")
22
26
  parser.add_argument(
23
27
  "action",
24
- choices=["list", "evaluate", "run", "step", "load", "http-server"],
28
+ choices=["list", "evaluate", "run", "step", "load", "act", "dispose", "http-server"],
25
29
  help="List environments. Evaluate many episodes. Run a single episode. Step the environment. Load the environment. Start http server.",
26
30
  )
27
- parser.add_argument("--environment", type=str,
28
- help="Environment to run against.")
31
+ parser.add_argument("--environment", type=str, help="Environment to run against.")
29
32
  parser.add_argument("--debug", type=bool, help="Print debug statements.")
30
- parser.add_argument(
31
- "--agents", type=str, nargs="*", help="Agent(s) to run with the environment."
32
- )
33
+ parser.add_argument("--agents", type=str, nargs="*", help="Agent(s) to run with the environment.")
33
34
  parser.add_argument(
34
35
  "--configuration",
35
36
  type=json.loads,
36
37
  help="Environment configuration to setup the environment.",
37
38
  )
39
+ parser.add_argument(
40
+ "--info",
41
+ type=json.loads,
42
+ help="Information about agents playing.",
43
+ )
38
44
  parser.add_argument(
39
45
  "--steps",
40
46
  type=json.loads,
41
47
  help="Environment starting states (default=[resetState]).",
42
48
  )
43
49
  parser.add_argument(
44
- "--episodes", type=int, help="Number of episodes to evaluate (default=1)"
50
+ "--logs",
51
+ type=json.loads,
52
+ help="Environment starting logs (default=[]).",
45
53
  )
54
+ parser.add_argument(
55
+ "--state",
56
+ type=json.loads,
57
+ help="Single agent state used for evaluation (default={}).",
58
+ )
59
+ parser.add_argument("--episodes", type=int, help="Number of episodes to evaluate (default=1)")
46
60
  parser.add_argument(
47
61
  "--render",
48
62
  type=json.loads,
49
- help="Response from run, step, or load. Calls environment render. (default={mode='json'})",
63
+ help="Response from run, step, or load. Calls environment render (default={mode='json'}).",
64
+ )
65
+ parser.add_argument(
66
+ "--display",
67
+ type=str,
68
+ help="Shortcut to the --render {mode=''} argument (default json).",
69
+ )
70
+ parser.add_argument("--port", type=int, help="http-server Port (default=8000).")
71
+ parser.add_argument("--host", type=str, help="http-server Host (default=127.0.0.1).")
72
+ parser.add_argument("--in", type=str, help="Episode replay file to load. Only works when the action is load.")
73
+ parser.add_argument(
74
+ "--out", type=str, help="Output file to write the results of the episode. Does nothing in http-server mode."
75
+ )
76
+ parser.add_argument(
77
+ "--log",
78
+ type=str,
79
+ help="Agent log file to write the std out, resource, and step timing for each agent. Also used to load logs from a file with the load action.",
50
80
  )
51
81
 
52
82
 
53
83
  def render(args, env):
54
- mode = utils.get(args.render, str, "json", path=["mode"])
55
- if mode == "human" or mode == "ansi":
84
+ mode = args.display if args.display is not None else utils.get(args.render, str, "json", path=["mode"])
85
+
86
+ if mode == "human" or mode == "ansi" or mode == "txt":
56
87
  args.render["mode"] = "ansi"
57
88
  elif mode == "ipython" or mode == "html":
58
89
  args.render["mode"] = "html"
90
+ elif mode == "webm" or mode == "video":
91
+ args.render["mode"] = "webm"
59
92
  else:
60
93
  args.render["mode"] = "json"
61
- return env.render(**args.render)
94
+ result = env.render(**args.render)
95
+ return result
62
96
 
63
97
 
64
98
  def action_list(args):
@@ -66,77 +100,180 @@ def action_list(args):
66
100
 
67
101
 
68
102
  def action_evaluate(args):
69
- return json.dumps(
70
- evaluate(
71
- args.environment, args.agents, args.configuration, args.steps, args.episodes
72
- )
73
- )
103
+ return json.dumps(evaluate(args.environment, args.agents, args.configuration, args.steps, args.episodes))
104
+
105
+
106
+ cached_agent = None
107
+
108
+
109
+ def action_act(args):
110
+ global cached_agent
111
+ if len(args.agents) != 1:
112
+ return {"error": "One agent must be provided."}
113
+ raw = args.agents[0]
114
+
115
+ env = make(args.environment, args.configuration, args.info, state=args.state, debug=args.debug)
116
+
117
+ is_first_run = cached_agent is None or cached_agent.raw != raw
118
+ if is_first_run:
119
+ cached_agent = Agent(raw, env)
120
+ observation = utils.get(args.state, dict, {}, ["observation"])
121
+ action, log = cached_agent.act(observation)
122
+ if isinstance(action, errors.DeadlineExceeded):
123
+ action = "DeadlineExceeded"
124
+ elif isinstance(action, BaseException):
125
+ action = "BaseException::" + str(action)
126
+
127
+ if args.log_path is not None:
128
+ with open(args.log_path, mode="a") as log_file:
129
+ if not is_first_run:
130
+ log_file.write(",\n ")
131
+ json.dump([log], log_file)
132
+
133
+ return {"action": action}
74
134
 
75
135
 
76
136
  def action_step(args):
77
- env = make(args.environment, args.configuration, args.steps, args.debug)
78
- env.step(env.__get_actions(args.agents))
137
+ env = {"logs": args.logs}
138
+ try:
139
+ env = make(args.environment, args.configuration, args.info, args.steps, args.logs, args.debug)
140
+ runner = env.__agent_runner(args.agents)
141
+ env.step(runner.act())
142
+ finally:
143
+ if args.log_path is not None:
144
+ with open(args.log_path, mode="a") as log_file:
145
+ json.dump(env.logs[-1], log_file)
146
+ log_file.write(",")
79
147
  return render(args, env)
80
148
 
81
149
 
82
150
  def action_run(args):
83
- env = make(args.environment, args.configuration, args.steps, args.debug)
84
- env.run(args.agents)
151
+ # Create a fake env so we can make the real env in our try body
152
+ env = utils.structify({"logs": args.logs})
153
+ try:
154
+ env = make(args.environment, args.configuration, args.info, args.steps, args.logs, args.debug)
155
+ env.run(args.agents)
156
+ finally:
157
+ if args.log_path is not None:
158
+ with open(args.log_path, mode="w") as log_file:
159
+ json.dump(env.logs, log_file, indent=2)
85
160
  return render(args, env)
86
161
 
87
162
 
88
163
  def action_load(args):
89
- env = make(args.environment, args.configuration, args.steps, args.debug)
164
+ if args.log_path is not None:
165
+ with open(args.log_path, mode="r") as log_file:
166
+ args.logs = json.load(log_file)
167
+
168
+ if args.in_path is not None:
169
+ with open(args.in_path, mode="r") as replay_file:
170
+ json_args = json.load(replay_file)
171
+ env = make(
172
+ json_args["name"], json_args["configuration"], json_args["info"], json_args["steps"], args.logs, args.debug
173
+ )
174
+ else:
175
+ env = make(args.environment, args.configuration, args.info, args.steps, args.logs, args.debug)
90
176
  return render(args, env)
91
177
 
92
178
 
93
- def action_handler(args):
94
- args = utils.structify(
179
+ disposed = True
180
+
181
+
182
+ # This method is only called at the end of an episode to write the final array brace in the logs file and dispose the cached agent to force reinitialization
183
+ def action_dispose(args):
184
+ global cached_agent, disposed
185
+ if disposed:
186
+ return "Already disposed"
187
+
188
+ cached_agent = None
189
+ if args.log_path is not None:
190
+ with open(args.log_path, mode="a") as log_file:
191
+ log_file.write("]")
192
+ disposed = True
193
+ return "Successfully disposed"
194
+
195
+
196
+ def parse_args(args):
197
+ return utils.structify(
95
198
  {
96
199
  "action": utils.get(args, str, "list", ["action"]),
97
200
  "agents": utils.get(args, list, [], ["agents"]),
98
201
  "configuration": utils.get(args, dict, {}, ["configuration"]),
99
- "environment": args.get("environment", None),
202
+ "environment": args.get("environment", args.get("name", None)),
100
203
  "episodes": utils.get(args, int, 1, ["episodes"]),
204
+ "state": utils.get(args, dict, {}, ["state"]),
101
205
  "steps": utils.get(args, list, [], ["steps"]),
206
+ "logs": utils.get(args, list, [], ["logs"]),
102
207
  "render": utils.get(args, dict, {"mode": "json"}, ["render"]),
103
- "debug": utils.get(args, bool, False, ["debug"])
208
+ "display": utils.get(args, str, None, ["display"]),
209
+ "debug": utils.get(args, bool, False, ["debug"]),
210
+ "host": utils.get(args, str, "127.0.0.1", ["host"]),
211
+ "port": utils.get(args, int, 8000, ["port"]),
212
+ "in_path": utils.get(args, str, None, ["in"]),
213
+ "out_path": utils.get(args, str, None, ["out"]),
214
+ "log_path": utils.get(args, str, None, ["log"]),
215
+ "info": utils.get(args, dict, {}, ["info"]),
104
216
  }
105
217
  )
106
218
 
107
- for index, agent in enumerate(args.agents):
108
- agent = utils.read_file(agent, agent)
109
- args.agents[index] = utils.get_last_callable(agent, agent)
110
-
111
- if args.action == "list":
112
- return action_list(args)
113
-
114
- if args.environment == None:
115
- return {"error": "Environment required."}
116
219
 
220
+ def action_handler(args):
117
221
  try:
222
+ if args.action == "list":
223
+ return action_list(args)
118
224
  if args.action == "http-server":
119
225
  return {"error": "Already running a http server."}
120
- elif args.action == "evaluate":
226
+ if args.action == "act":
227
+ return action_act(args)
228
+ if args.action == "dispose":
229
+ return action_dispose(args)
230
+ if args.action == "load":
231
+ return action_load(args)
232
+
233
+ if args.environment is None:
234
+ return {"error": "Environment required."}
235
+
236
+ if args.action == "evaluate":
121
237
  return action_evaluate(args)
122
- elif args.action == "step":
238
+ if args.action == "step":
123
239
  return action_step(args)
124
- elif args.action == "run":
240
+ if args.action == "run":
125
241
  return action_run(args)
126
- elif args.action == "load":
127
- return action_load(args)
128
- else:
129
- return {"error": "Unknown Action"}
242
+
243
+ return {"error": "Unknown Action"}
130
244
  except Exception as e:
131
245
  return {"error": str(e), "trace": traceback.format_exc()}
132
246
 
133
247
 
248
+ log_path: Optional[str] = None
249
+
250
+
134
251
  def action_http(args):
135
252
  from flask import Flask, request
136
253
 
254
+ if args.log_path is not None:
255
+ global log_path
256
+ log_path = args.log_path
257
+
258
+ # Setup logging to console for Flask
259
+ dictConfig(
260
+ {
261
+ "version": 1,
262
+ "formatters": {
263
+ "default": {
264
+ "format": "%(levelname)s: %(message)s",
265
+ }
266
+ },
267
+ "handlers": {
268
+ "wsgi": {"class": "logging.StreamHandler", "stream": "ext://sys.stdout", "formatter": "default"}
269
+ },
270
+ "root": {"level": "INFO", "handlers": ["wsgi"]},
271
+ }
272
+ )
273
+
137
274
  app = Flask(__name__, static_url_path="", static_folder="")
138
275
  app.route("/", methods=["GET", "POST"])(lambda: http_request(request))
139
- app.run("127.0.0.1", 8000, debug=True)
276
+ app.run(args.host, args.port, debug=args.debug, use_reloader=args.debug)
140
277
 
141
278
 
142
279
  def http_request(request):
@@ -151,10 +288,9 @@ def http_request(request):
151
288
  "Access-Control-Max-Age": "3600",
152
289
  }
153
290
 
154
- return ("", 204, headers)
291
+ return "", 204, headers
155
292
 
156
293
  headers = {"Access-Control-Allow-Origin": "*"}
157
-
158
294
  params = request.args.to_dict()
159
295
  for key in list(params.keys()):
160
296
  if key.endswith("[]"):
@@ -166,11 +302,39 @@ def http_request(request):
166
302
 
167
303
  body = request.get_json(silent=True, force=True) or {}
168
304
  args = {**params, **body}
169
- return (action_handler(args), 200, headers)
305
+ if "render" in args and isinstance(args["render"], str):
306
+ # Manually deserialize render argument
307
+ # We should eventually refactor this to use the same deserializer as the cmd line arg parser
308
+ args["render"] = json.loads(args["render"])
309
+ args = parse_args(args)
310
+ if args.log_path is None:
311
+ args.log_path = log_path
312
+
313
+ global disposed
314
+ # Write the opening array brace for the logs file if there is a logs file.
315
+ if disposed and args["action"] != "dispose" and args.log_path is not None:
316
+ with open(args.log_path, mode="w") as log_file:
317
+ log_file.write("[")
318
+ disposed = False
319
+
320
+ resp = action_handler(args)
321
+ return resp, 200, headers
322
+
323
+
324
+ def main():
325
+ args = parse_args(vars(parser.parse_args()))
326
+ if args.action == "http-server":
327
+ action_http(args)
328
+ else:
329
+ result = action_handler(args)
330
+ if args.out_path is None:
331
+ print(result)
332
+ else:
333
+ with open(args.out_path, encoding="utf-8", mode="w") as out_file:
334
+ out_file.write(str(result))
335
+
336
+ return 0
170
337
 
171
338
 
172
339
  if __name__ == "__main__":
173
- args = parser.parse_args()
174
- if args.action == "http-server":
175
- action_http(args)
176
- print(action_handler(vars(args)))
340
+ main()
@@ -62,29 +62,17 @@
62
62
  "minimum": 1,
63
63
  "default": 1000
64
64
  },
65
- "agentExec": {
66
- "description": "How the agent is executed alongside the running envionment.",
67
- "type": "string",
68
- "default": "PROCESS",
69
- "enum": ["LOCAL", "PROCESS"]
70
- },
71
- "agentTimeout": {
72
- "description": "Maximum runtime (seconds) to initialize an agent.",
73
- "type": "integer",
74
- "minimum": 1,
75
- "default": 10
76
- },
77
65
  "actTimeout": {
78
66
  "description": "Maximum runtime (seconds) to obtain an action from an agent.",
79
- "type": "integer",
80
- "minimum": 1,
81
- "default": 2
67
+ "type": "number",
68
+ "minimum": 0,
69
+ "default": 6
82
70
  },
83
71
  "runTimeout": {
84
72
  "description": "Maximum runtime (seconds) of an episode (not necessarily DONE).",
85
- "type": "integer",
86
- "minimum": 1,
87
- "default": 600
73
+ "type": "number",
74
+ "minimum": 0,
75
+ "default": 1200
88
76
  }
89
77
  }
90
78
  },
@@ -110,6 +98,23 @@
110
98
  "observation": {
111
99
  "description": "Observation to create an action based upon.",
112
100
  "type": "object",
101
+ "additionalProperties": true,
102
+ "properties": {
103
+ "remainingOverageTime": {
104
+ "description": "Total remaining banked time (seconds) that can be used in excess of per-step actTimeouts -- agent is disqualified with TIMEOUT status when this drops below 0.",
105
+ "shared": false,
106
+ "type": "number",
107
+ "minimum": 0,
108
+ "default": 12
109
+ },
110
+ "step": {
111
+ "description": "Current step within the episode.",
112
+ "type": "integer",
113
+ "shared": true,
114
+ "minimum": 0,
115
+ "default": 0
116
+ }
117
+ },
113
118
  "default": {}
114
119
  },
115
120
  "status": {