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
@@ -12,29 +12,65 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import os
15
16
  from importlib import import_module
16
17
  from os import listdir
17
18
  from .agent import Agent
18
- from .core import *
19
+ from .api import get_episode_replay, list_episodes, list_episodes_for_team, list_episodes_for_submission
20
+ from .core import evaluate, make, register
21
+ from .main import http_request
19
22
  from . import errors
20
23
  from . import utils
21
24
 
22
- version = "0.2.0"
25
+ __version__ = "1.19.0"
23
26
 
24
- __all__ = ["Agent", "environments", "errors", "evaluate",
25
- "make", "register", "utils", "version"]
27
+ __all__ = [
28
+ "Agent",
29
+ "environments",
30
+ "errors",
31
+ "evaluate",
32
+ "http_request",
33
+ "make",
34
+ "register",
35
+ "utils",
36
+ "__version__",
37
+ "get_episode_replay",
38
+ "list_episodes",
39
+ "list_episodes_for_team",
40
+ "list_episodes_for_submission",
41
+ ]
42
+
43
+ _script_dir = os.path.dirname(os.path.realpath(__file__))
44
+ PROJECT_ROOT = os.path.abspath(os.path.join('..', _script_dir))
26
45
 
27
46
  # Register Environments.
28
47
 
29
48
  for name in listdir(utils.envs_path):
30
49
  try:
31
50
  env = import_module(f".envs.{name}.{name}", __name__)
32
- register(name, {
33
- "agents": getattr(env, "agents", []),
34
- "html_renderer": getattr(env, "html_renderer", None),
35
- "interpreter": getattr(env, "interpreter"),
36
- "renderer": getattr(env, "renderer"),
37
- "specification": getattr(env, "specification"),
38
- })
39
- except:
40
- pass
51
+ if name == "open_spiel":
52
+ for env_name, env_dict in env.ENV_REGISTRY.items():
53
+ register(
54
+ env_name,
55
+ {
56
+ "agents": env_dict.get("agents"),
57
+ "html_renderer": env_dict.get("html_renderer"),
58
+ "interpreter": env_dict.get("interpreter"),
59
+ "renderer": env_dict.get("renderer"),
60
+ "specification": env_dict.get("specification"),
61
+ },
62
+ )
63
+ else:
64
+ register(
65
+ name,
66
+ {
67
+ "agents": getattr(env, "agents", []),
68
+ "html_renderer": getattr(env, "html_renderer", None),
69
+ "interpreter": getattr(env, "interpreter"),
70
+ "renderer": getattr(env, "renderer"),
71
+ "specification": getattr(env, "specification"),
72
+ },
73
+ )
74
+ except Exception as e:
75
+ if "football" not in name:
76
+ print("Loading environment %s failed: %s" % (name, e))
@@ -12,151 +12,204 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import json
15
16
  import os
17
+ import sys
18
+ import traceback
19
+ from contextlib import redirect_stderr, redirect_stdout
20
+ from io import StringIO
21
+ from time import perf_counter
22
+ from urllib.parse import urlparse
23
+
16
24
  import requests
17
- import json
18
- from multiprocessing import Manager, Process
19
- from time import time
20
- import uuid
21
- from .errors import DeadlineExceeded
22
- from .utils import get_exec, has, is_url, read_file, structify
25
+ from requests.exceptions import Timeout
26
+
27
+ from .errors import DeadlineExceeded, InvalidArgument
28
+ from .utils import read_file, structify
29
+
23
30
 
31
+ def is_url(url):
32
+ try:
33
+ result = urlparse(url)
34
+ return all([result.scheme, result.netloc])
35
+ except ValueError:
36
+ return False
37
+
38
+
39
+ def get_last_callable(raw, fallback=None, path=None):
40
+ orig_out = sys.stdout
41
+ buffer = StringIO()
42
+ sys.stdout = buffer
43
+
44
+ try:
45
+ code_object = compile(raw, path, "exec")
46
+ env = {}
47
+
48
+ # append exec_dir so that way python agents can import other files
49
+ exec_dir = os.path.dirname(path)
50
+ sys.path.append(exec_dir)
51
+
52
+ exec(code_object, env)
53
+ sys.path.pop()
54
+ sys.stdout = orig_out
55
+ output = buffer.getvalue()
56
+ if output:
57
+ print(output)
58
+ return [v for v in env.values() if callable(v)][-1]
59
+ except Exception as e:
60
+ sys.stdout = orig_out
61
+ output = buffer.getvalue()
62
+ if output:
63
+ print(output)
64
+ if fallback is not None:
65
+ return fallback
66
+ raise InvalidArgument("Invalid raw Python: " + repr(e))
67
+
68
+
69
+ class UrlAgent:
70
+ def __init__(self, raw, environment_name):
71
+ self.raw = raw
72
+ self.environment_name = environment_name
73
+
74
+ def __call__(self, observation, configuration):
75
+ data = {
76
+ "action": "act",
77
+ "configuration": configuration,
78
+ "environment": self.environment_name,
79
+ "state": {
80
+ "observation": observation,
81
+ },
82
+ }
83
+ timeout = float(observation.remainingOverageTime) + float(configuration.actTimeout) + 1
84
+ try:
85
+ response = requests.post(url=self.raw, data=json.dumps(data), timeout=timeout)
86
+ response.raise_for_status()
87
+ response_json = response.json()
88
+ action = response_json["action"]
89
+ if action == "DeadlineExceeded":
90
+ action = DeadlineExceeded()
91
+ elif isinstance(action, str) and action.startswith("BaseException::"):
92
+ # Deserialize the exception message
93
+ parts = action.split("::", 1)
94
+ action = BaseException(parts[1])
95
+ return action
96
+ except Timeout:
97
+ print(f"Request timed out after {timeout} seconds")
98
+ return DeadlineExceeded()
99
+ except requests.exceptions.RequestException as e:
100
+ print(f"Request error: {e}")
101
+ return None
102
+
103
+
104
+ def build_agent(raw, builtin_agents, environment_name):
105
+ """
106
+ Returns the agent and whether the agent is parallelizable.
107
+ """
108
+ if raw in builtin_agents:
109
+ agent = builtin_agents[raw]
110
+ # TODO: Below is a hack. Assuming an agent is a global callable is not enough to guarantee it is stateless.
111
+ # Kaggle environment should allow more scalable agent initialization and proper agent interface design.
112
+ if hasattr(agent, "reset"):
113
+ agent.reset()
114
+ return builtin_agents[raw], False
24
115
 
25
- def build_agent(raw):
26
116
  # Already callable.
27
117
  if callable(raw):
28
- return raw
118
+ return raw, False
29
119
 
30
120
  # Not a string, static action.
31
- if not has(raw, str):
32
- return lambda: raw
121
+ if not isinstance(raw, str):
122
+ return lambda: raw, False
33
123
 
34
124
  # A URL and will be initialized on the calling server.
35
125
  if is_url(raw):
36
- def url_agent(o, c, r, i):
37
- data = {
38
- "action": "act",
39
- "configuration": {
40
- **c,
41
- "agentExec": "LOCAL"
42
- },
43
- "state": {
44
- "observation": o,
45
- "reward": r,
46
- "info": i
47
- }
48
- }
49
- action = requests.post(
50
- url=raw, data=json.dumps(data)).json()["action"]
51
- if action == "DeadlineExceeded":
52
- action = DeadlineExceeded()
53
- elif action == "BaseException":
54
- action = BaseException()
55
- return action
56
- return url_agent
126
+ return UrlAgent(raw, environment_name), True
57
127
 
58
128
  # A path exists and attempt to grab the source (fallback to the original string).
129
+ raw_agent = raw
59
130
  if os.path.exists(raw):
60
- raw = read_file(raw, raw)
131
+ raw_agent = read_file(raw, raw)
132
+ elif (len(raw) < 100 and ("/" in raw or "\\" in raw)) or len(raw) < 20:
133
+ raise FileNotFoundError("Could not find : " + raw)
61
134
 
62
135
  # Attempt to execute the last callable or just return the string.
63
- try:
64
- local = get_exec(raw)
65
- callables = [v for v in local.values() if callable(v)]
66
- if len(callables) > 0:
67
- return callables[-1]
68
- raise "Nope"
69
- except:
70
- return lambda: raw
71
-
72
-
73
- def run_agent(agent, message):
74
- if message.state != None and message:
75
- args = [
76
- structify(message.state["observation"]),
77
- structify(message.configuration),
78
- message.state["reward"],
79
- structify(message.state["info"])
80
- ][:agent.__code__.co_argcount]
81
- try:
82
- message.action = agent(*args)
83
- except Exception as e:
84
- message.action = e
85
- message.state = None
86
-
87
-
88
- def runner(raw, message):
89
- try:
90
- agent = build_agent(raw)
91
- except Exception as e:
92
- message.action = e
93
- while True:
94
- run_agent(agent, message)
95
-
96
-
97
- class Agent():
98
-
99
- def __init__(self, raw, configuration, id=None):
100
- self.id = id or str(uuid.uuid1())
101
- self.configuration = configuration
136
+ agent = None
137
+
138
+ def callable_agent(observation, configuration):
139
+ nonlocal agent
140
+ if agent is None:
141
+ agent = get_last_callable(raw_agent, path=raw) or raw_agent
142
+ configuration["__raw_path__"] = raw
143
+ args = [observation, configuration]
144
+ args = args[: agent.__code__.co_argcount]
145
+ return agent(*args) if callable(agent) else agent
146
+
147
+ return callable_agent, False
148
+
149
+
150
+ class Agent:
151
+ def __init__(self, raw, environment):
152
+ self.builtin_agents = environment.agents
153
+ self.configuration = environment.configuration
154
+ self.debug = environment.debug
155
+ self.environment_name = environment.name
102
156
  self.raw = raw
103
- self.use_process = configuration["agentExec"] == "PROCESS"
104
-
105
- if self.use_process:
106
- self.manager = Manager()
107
- self.message = self.manager.Namespace()
108
- self.message.action = None
109
- self.message.state = None
110
- self.message.configuration = configuration
111
- self.process = Process(target=runner, args=(raw, self.message))
112
- self.process.daemon = True
113
- self.process.start()
114
- else:
115
- self.message = structify(
116
- {"action": None, "state": None, "configuration": configuration})
117
- self.agent = None
157
+ self.agent, self.is_parallelizable = build_agent(self.raw, self.builtin_agents, self.environment_name)
118
158
 
119
- def act(self, state, timeout=10):
120
- # Start the timer.
121
- start = time()
159
+ def act(self, observation):
160
+ args = [structify(observation), structify(self.configuration)]
122
161
 
123
- # If an action is already set (uncleared), there is an error.
124
- if self.message.action != None:
125
- return self.message.action
162
+ if hasattr(self.agent, "__code__"):
163
+ args = args[: self.agent.__code__.co_argcount]
126
164
 
127
- # Inform the agent an action is requested.
128
- self.message.state = state
165
+ # Start the timer.
129
166
 
130
- if self.use_process:
131
- # Timeout or Action Returned (will be processed below).
132
- while True:
133
- if time() - start > timeout or self.message.action != None:
134
- break
167
+ if self.debug:
168
+ # Adding a debugging branch here, since the context manager and try except would prevent
169
+ # debugger from functioning properly.
170
+ start = perf_counter()
171
+ action = self.agent(*args)
172
+ out = ""
173
+ err = ""
135
174
  else:
136
- if self.agent is None:
175
+ with (
176
+ StringIO() as out_buffer,
177
+ StringIO() as err_buffer,
178
+ redirect_stdout(out_buffer),
179
+ redirect_stderr(err_buffer),
180
+ ):
137
181
  try:
138
- self.agent = build_agent(self.raw)
139
- # Update the timeout to add the agentTimeout (incase set to "act").
140
- timeout = self.configuration.agentTimeout + self.configuration.actTimeout
182
+ start = perf_counter()
183
+ action = self.agent(*args)
141
184
  except Exception as e:
142
- return e
143
- run_agent(self.agent, self.message)
144
-
145
- # Timeout reached, destroy the agent, and throw an error.
146
- if time() - start > timeout:
147
- self.destroy()
148
- return DeadlineExceeded()
149
-
150
- # Return and clear the action.
151
- action = self.message.action
152
- self.message.action = None
153
- return action
154
-
155
- def destroy(self):
156
- if self.id == None:
157
- return
158
- self.id = None
159
- if self.use_process:
160
- self.process.join(0.1)
161
- self.process.terminate()
162
- self.manager.shutdown()
185
+ traceback.print_exc(file=err_buffer)
186
+ action = e
187
+ out = out_buffer.getvalue()
188
+ err = err_buffer.getvalue()
189
+ # Get the maximum log length
190
+ # Allow up to 10k (default) log characters per step which is ~10MB per 600 step episode
191
+ max_log_length = self.configuration.get("maxLogLength", 10000)
192
+
193
+ # truncate if max_log_length is set to None, do not truncate
194
+ if max_log_length is not None:
195
+ out = out[0:max_log_length]
196
+ err = err[0:max_log_length]
197
+
198
+ duration = perf_counter() - start
199
+ log = {
200
+ "duration": round(duration, 6),
201
+ "stdout": out,
202
+ "stderr": err,
203
+ }
204
+
205
+ if self.debug:
206
+ if not log["stdout"].isspace():
207
+ print(log["stdout"], end="")
208
+ if not log["stderr"].isspace():
209
+ print(log["stderr"], end="")
210
+
211
+ if duration - self.configuration.actTimeout > observation.remainingOverageTime:
212
+ # No overage time left, timeout agent
213
+ action = DeadlineExceeded()
214
+
215
+ return action, log
@@ -0,0 +1,31 @@
1
+ from typing import List
2
+
3
+ import requests
4
+
5
+ base_url = "https://www.kaggle.com/requests/EpisodeService/"
6
+ get_url = base_url + "GetEpisodeReplay"
7
+ list_url = base_url + "ListEpisodes"
8
+
9
+
10
+ def get_episode_replay(episode_id: int):
11
+ body = {"EpisodeId": episode_id}
12
+
13
+ response = requests.post(get_url, json=body)
14
+ return response.json()
15
+
16
+
17
+ def list_episodes(episode_ids: List[int]):
18
+ return __list_episodes({"Ids": episode_ids})
19
+
20
+
21
+ def list_episodes_for_team(team_id: int):
22
+ return __list_episodes({"TeamId": team_id})
23
+
24
+
25
+ def list_episodes_for_submission(submission_id: int):
26
+ return __list_episodes({"SubmissionId": submission_id})
27
+
28
+
29
+ def __list_episodes(body):
30
+ response = requests.post(list_url, json=body)
31
+ return response.json()