rapidfireai 0.0.1__py3-none-any.whl → 0.9.10__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 rapidfireai might be problematic. Click here for more details.

Files changed (320) hide show
  1. rapidfireai/__init__.py +11 -5
  2. rapidfireai/automl/__init__.py +20 -0
  3. rapidfireai/automl/base.py +48 -0
  4. rapidfireai/automl/datatypes.py +42 -0
  5. rapidfireai/automl/grid_search.py +125 -0
  6. rapidfireai/automl/model_config.py +102 -0
  7. rapidfireai/automl/random_search.py +145 -0
  8. rapidfireai/backend/__init__.py +0 -0
  9. rapidfireai/backend/chunks.py +63 -0
  10. rapidfireai/backend/controller.py +637 -0
  11. rapidfireai/backend/scheduler.py +137 -0
  12. rapidfireai/backend/worker.py +272 -0
  13. rapidfireai/cli.py +380 -0
  14. rapidfireai/db/__init__.py +0 -0
  15. rapidfireai/db/db_interface.py +135 -0
  16. rapidfireai/db/rf_db.py +694 -0
  17. rapidfireai/db/tables.sql +64 -0
  18. rapidfireai/dispatcher/dispatcher.py +391 -0
  19. rapidfireai/dispatcher/gunicorn.conf.py +25 -0
  20. rapidfireai/experiment.py +168 -0
  21. rapidfireai/frontend/build/asset-manifest.json +276 -0
  22. rapidfireai/frontend/build/favicon.ico +0 -0
  23. rapidfireai/frontend/build/index.html +1 -0
  24. rapidfireai/frontend/build/manifest.json +15 -0
  25. rapidfireai/frontend/build/pdf.worker.js +1 -0
  26. rapidfireai/frontend/build/report.html +39 -0
  27. rapidfireai/frontend/build/static/css/1482.3b7bf531.chunk.css +1 -0
  28. rapidfireai/frontend/build/static/css/2730.3f8937ff.chunk.css +1 -0
  29. rapidfireai/frontend/build/static/css/318.0def90a7.css +7 -0
  30. rapidfireai/frontend/build/static/css/4762.9b7b71f7.chunk.css +1 -0
  31. rapidfireai/frontend/build/static/css/4950.487ecc8b.chunk.css +1 -0
  32. rapidfireai/frontend/build/static/css/5170.2574ce9d.chunk.css +1 -0
  33. rapidfireai/frontend/build/static/css/6121.4d541986.chunk.css +1 -0
  34. rapidfireai/frontend/build/static/css/6343.dd6979f2.chunk.css +1 -0
  35. rapidfireai/frontend/build/static/css/6534.433c213f.chunk.css +1 -0
  36. rapidfireai/frontend/build/static/css/6920.ffac4b2a.css +2 -0
  37. rapidfireai/frontend/build/static/css/7246.bf2f0c87.css +9 -0
  38. rapidfireai/frontend/build/static/css/7367.dd6979f2.chunk.css +1 -0
  39. rapidfireai/frontend/build/static/css/8690.05d081e5.chunk.css +1 -0
  40. rapidfireai/frontend/build/static/css/9531.d0910d3c.chunk.css +1 -0
  41. rapidfireai/frontend/build/static/css/9780.363e4943.chunk.css +1 -0
  42. rapidfireai/frontend/build/static/css/main~d91a9049.c0be472c.css +1 -0
  43. rapidfireai/frontend/build/static/js/1000.e5ed264b.chunk.js +1 -0
  44. rapidfireai/frontend/build/static/js/1012.ac98ab59.chunk.js +1 -0
  45. rapidfireai/frontend/build/static/js/1079.6c13ac0d.js +1 -0
  46. rapidfireai/frontend/build/static/js/110.9059f3b8.chunk.js +1 -0
  47. rapidfireai/frontend/build/static/js/1142.872d0010.chunk.js +1 -0
  48. rapidfireai/frontend/build/static/js/1167.9a6da14c.chunk.js +1 -0
  49. rapidfireai/frontend/build/static/js/1248.60890b4f.chunk.js +1 -0
  50. rapidfireai/frontend/build/static/js/1262.83dc7673.chunk.js +1 -0
  51. rapidfireai/frontend/build/static/js/1273.56da3e13.chunk.js +2 -0
  52. rapidfireai/frontend/build/static/js/1273.56da3e13.chunk.js.LICENSE.txt +9 -0
  53. rapidfireai/frontend/build/static/js/1303.7d19305c.chunk.js +1 -0
  54. rapidfireai/frontend/build/static/js/1351.45076ff3.chunk.js +1 -0
  55. rapidfireai/frontend/build/static/js/1355.b896a592.js +1 -0
  56. rapidfireai/frontend/build/static/js/1357.02c46a02.chunk.js +1 -0
  57. rapidfireai/frontend/build/static/js/1470.c51d60c6.chunk.js +1 -0
  58. rapidfireai/frontend/build/static/js/1482.23b74f50.chunk.js +1 -0
  59. rapidfireai/frontend/build/static/js/1500.19799d8d.chunk.js +1 -0
  60. rapidfireai/frontend/build/static/js/1648.d3b9edc7.chunk.js +1 -0
  61. rapidfireai/frontend/build/static/js/1860.7d96e3f9.chunk.js +1 -0
  62. rapidfireai/frontend/build/static/js/1909.5b1d9ff4.chunk.js +1 -0
  63. rapidfireai/frontend/build/static/js/1928.44245110.chunk.js +2 -0
  64. rapidfireai/frontend/build/static/js/1928.44245110.chunk.js.LICENSE.txt +11 -0
  65. rapidfireai/frontend/build/static/js/1933.deba26ca.chunk.js +1 -0
  66. rapidfireai/frontend/build/static/js/21.aac92802.chunk.js +1 -0
  67. rapidfireai/frontend/build/static/js/2103.0ca12071.chunk.js +1 -0
  68. rapidfireai/frontend/build/static/js/2258.b3b8fab4.chunk.js +1 -0
  69. rapidfireai/frontend/build/static/js/2289.9ad51e87.chunk.js +1 -0
  70. rapidfireai/frontend/build/static/js/2323.7dd927d7.js +2 -0
  71. rapidfireai/frontend/build/static/js/2323.7dd927d7.js.LICENSE.txt +1 -0
  72. rapidfireai/frontend/build/static/js/2346.ed99ca72.chunk.js +1 -0
  73. rapidfireai/frontend/build/static/js/2386.0a660834.chunk.js +1 -0
  74. rapidfireai/frontend/build/static/js/2402.465048f9.chunk.js +1 -0
  75. rapidfireai/frontend/build/static/js/243.5a83bbca.chunk.js +1 -0
  76. rapidfireai/frontend/build/static/js/2589.68571e16.js +1 -0
  77. rapidfireai/frontend/build/static/js/2647.65092bab.chunk.js +1 -0
  78. rapidfireai/frontend/build/static/js/2691.65d4a4e7.js +1 -0
  79. rapidfireai/frontend/build/static/js/2730.b38dd6f3.chunk.js +1 -0
  80. rapidfireai/frontend/build/static/js/2746.ef752da4.chunk.js +1 -0
  81. rapidfireai/frontend/build/static/js/2779.580d4491.chunk.js +1 -0
  82. rapidfireai/frontend/build/static/js/2799.fe5993b2.chunk.js +1 -0
  83. rapidfireai/frontend/build/static/js/2844.9708db79.chunk.js +2 -0
  84. rapidfireai/frontend/build/static/js/2844.9708db79.chunk.js.LICENSE.txt +21 -0
  85. rapidfireai/frontend/build/static/js/2901.ee0c606b.chunk.js +1 -0
  86. rapidfireai/frontend/build/static/js/2932.7cc0689b.chunk.js +2 -0
  87. rapidfireai/frontend/build/static/js/2932.7cc0689b.chunk.js.LICENSE.txt +6 -0
  88. rapidfireai/frontend/build/static/js/2956.a393c8cc.chunk.js +1 -0
  89. rapidfireai/frontend/build/static/js/2972.679bed05.chunk.js +1 -0
  90. rapidfireai/frontend/build/static/js/2985.7e51cdfa.chunk.js +2 -0
  91. rapidfireai/frontend/build/static/js/2985.7e51cdfa.chunk.js.LICENSE.txt +51 -0
  92. rapidfireai/frontend/build/static/js/3093.488df653.js +1 -0
  93. rapidfireai/frontend/build/static/js/3145.66ee61b9.js +1 -0
  94. rapidfireai/frontend/build/static/js/3170.a22f966a.chunk.js +2 -0
  95. rapidfireai/frontend/build/static/js/3170.a22f966a.chunk.js.LICENSE.txt +21 -0
  96. rapidfireai/frontend/build/static/js/3307.f6fb258c.chunk.js +1 -0
  97. rapidfireai/frontend/build/static/js/3325.d5b03d65.js +1 -0
  98. rapidfireai/frontend/build/static/js/3334.2d6704df.chunk.js +2 -0
  99. rapidfireai/frontend/build/static/js/3334.2d6704df.chunk.js.LICENSE.txt +6 -0
  100. rapidfireai/frontend/build/static/js/3387.bb8edad3.chunk.js +1 -0
  101. rapidfireai/frontend/build/static/js/3448.438e6579.chunk.js +1 -0
  102. rapidfireai/frontend/build/static/js/3460.735eea87.chunk.js +1 -0
  103. rapidfireai/frontend/build/static/js/3505.7fd3921a.js +2 -0
  104. rapidfireai/frontend/build/static/js/3505.7fd3921a.js.LICENSE.txt +9 -0
  105. rapidfireai/frontend/build/static/js/3510.cd167a00.js +2 -0
  106. rapidfireai/frontend/build/static/js/3510.cd167a00.js.LICENSE.txt +18 -0
  107. rapidfireai/frontend/build/static/js/3563.cc828e19.chunk.js +1 -0
  108. rapidfireai/frontend/build/static/js/359.08960b84.chunk.js +2 -0
  109. rapidfireai/frontend/build/static/js/359.08960b84.chunk.js.LICENSE.txt +4 -0
  110. rapidfireai/frontend/build/static/js/3608.403b4b79.chunk.js +1 -0
  111. rapidfireai/frontend/build/static/js/3652.cb8add7f.js +1 -0
  112. rapidfireai/frontend/build/static/js/3775.5230b157.chunk.js +1 -0
  113. rapidfireai/frontend/build/static/js/3817.53555d18.js +2 -0
  114. rapidfireai/frontend/build/static/js/3817.53555d18.js.LICENSE.txt +18 -0
  115. rapidfireai/frontend/build/static/js/3835.d9946ff9.chunk.js +1 -0
  116. rapidfireai/frontend/build/static/js/3964.874f0297.chunk.js +1 -0
  117. rapidfireai/frontend/build/static/js/3968.275cbc3d.chunk.js +1 -0
  118. rapidfireai/frontend/build/static/js/3999.765cbd82.chunk.js +1 -0
  119. rapidfireai/frontend/build/static/js/4020.4452c046.chunk.js +1 -0
  120. rapidfireai/frontend/build/static/js/4138.2f6f6d9f.js +1 -0
  121. rapidfireai/frontend/build/static/js/4160.f424554c.js +1 -0
  122. rapidfireai/frontend/build/static/js/4180.50cea095.chunk.js +1 -0
  123. rapidfireai/frontend/build/static/js/4221.b0bba3f5.chunk.js +1 -0
  124. rapidfireai/frontend/build/static/js/4250.5bb49278.chunk.js +1 -0
  125. rapidfireai/frontend/build/static/js/4297.15777d8f.chunk.js +1 -0
  126. rapidfireai/frontend/build/static/js/4349.c965f2de.js +2 -0
  127. rapidfireai/frontend/build/static/js/4349.c965f2de.js.LICENSE.txt +1 -0
  128. rapidfireai/frontend/build/static/js/4484.4cbe5e7f.js +2 -0
  129. rapidfireai/frontend/build/static/js/4484.4cbe5e7f.js.LICENSE.txt +10 -0
  130. rapidfireai/frontend/build/static/js/4578.a8124588.js +1 -0
  131. rapidfireai/frontend/build/static/js/4596.89a97480.js +1 -0
  132. rapidfireai/frontend/build/static/js/4748.566f435a.chunk.js +1 -0
  133. rapidfireai/frontend/build/static/js/4762.928e8a90.chunk.js +1 -0
  134. rapidfireai/frontend/build/static/js/4768.7945be63.js +2 -0
  135. rapidfireai/frontend/build/static/js/4768.7945be63.js.LICENSE.txt +1 -0
  136. rapidfireai/frontend/build/static/js/4804.26b50dd4.chunk.js +1 -0
  137. rapidfireai/frontend/build/static/js/4850.62390a45.chunk.js +1 -0
  138. rapidfireai/frontend/build/static/js/4862.a0ccb221.chunk.js +1 -0
  139. rapidfireai/frontend/build/static/js/491.5dc8ed40.chunk.js +1 -0
  140. rapidfireai/frontend/build/static/js/492.9262f038.chunk.js +2 -0
  141. rapidfireai/frontend/build/static/js/492.9262f038.chunk.js.LICENSE.txt +6 -0
  142. rapidfireai/frontend/build/static/js/4943.6d345fd3.chunk.js +1 -0
  143. rapidfireai/frontend/build/static/js/4950.bc182e62.chunk.js +1 -0
  144. rapidfireai/frontend/build/static/js/5042.d4f0c65a.chunk.js +2 -0
  145. rapidfireai/frontend/build/static/js/5042.d4f0c65a.chunk.js.LICENSE.txt +6 -0
  146. rapidfireai/frontend/build/static/js/5170.0065e96f.chunk.js +1 -0
  147. rapidfireai/frontend/build/static/js/5222.35c74a52.js +2 -0
  148. rapidfireai/frontend/build/static/js/5222.35c74a52.js.LICENSE.txt +10 -0
  149. rapidfireai/frontend/build/static/js/5223.3224f019.chunk.js +2 -0
  150. rapidfireai/frontend/build/static/js/5223.3224f019.chunk.js.LICENSE.txt +3 -0
  151. rapidfireai/frontend/build/static/js/5229.7dd42316.chunk.js +1 -0
  152. rapidfireai/frontend/build/static/js/5286.4c1ad26b.js +1 -0
  153. rapidfireai/frontend/build/static/js/5486.21cff711.chunk.js +1 -0
  154. rapidfireai/frontend/build/static/js/5526.7b368956.chunk.js +1 -0
  155. rapidfireai/frontend/build/static/js/5605.1ee4d87b.chunk.js +1 -0
  156. rapidfireai/frontend/build/static/js/5682.40b42d8b.chunk.js +1 -0
  157. rapidfireai/frontend/build/static/js/5794.9433d867.chunk.js +1 -0
  158. rapidfireai/frontend/build/static/js/5826.38a56e8c.chunk.js +2 -0
  159. rapidfireai/frontend/build/static/js/5826.38a56e8c.chunk.js.LICENSE.txt +1 -0
  160. rapidfireai/frontend/build/static/js/5862.50f42a0b.js +1 -0
  161. rapidfireai/frontend/build/static/js/5895.e26742f1.chunk.js +1 -0
  162. rapidfireai/frontend/build/static/js/5919.edd4a5cf.chunk.js +1 -0
  163. rapidfireai/frontend/build/static/js/598.a0e792ae.js +1 -0
  164. rapidfireai/frontend/build/static/js/6058.74162bf9.chunk.js +1 -0
  165. rapidfireai/frontend/build/static/js/618.06051134.chunk.js +2 -0
  166. rapidfireai/frontend/build/static/js/618.06051134.chunk.js.LICENSE.txt +21 -0
  167. rapidfireai/frontend/build/static/js/6335.9fca442d.chunk.js +1 -0
  168. rapidfireai/frontend/build/static/js/6336.e05e1154.chunk.js +1 -0
  169. rapidfireai/frontend/build/static/js/6343.2bcd28ff.chunk.js +1 -0
  170. rapidfireai/frontend/build/static/js/6363.a319b8f2.chunk.js +1 -0
  171. rapidfireai/frontend/build/static/js/6478.344abf25.chunk.js +1 -0
  172. rapidfireai/frontend/build/static/js/6504.1c004564.js +1 -0
  173. rapidfireai/frontend/build/static/js/6534.ec7e149b.chunk.js +1 -0
  174. rapidfireai/frontend/build/static/js/6715.55a5c19c.chunk.js +1 -0
  175. rapidfireai/frontend/build/static/js/6756.e6cb993c.chunk.js +2 -0
  176. rapidfireai/frontend/build/static/js/6756.e6cb993c.chunk.js.LICENSE.txt +10 -0
  177. rapidfireai/frontend/build/static/js/6762.acfde9fd.chunk.js +2 -0
  178. rapidfireai/frontend/build/static/js/6762.acfde9fd.chunk.js.LICENSE.txt +19 -0
  179. rapidfireai/frontend/build/static/js/6846.67103d0e.chunk.js +1 -0
  180. rapidfireai/frontend/build/static/js/6861.34cf0198.chunk.js +1 -0
  181. rapidfireai/frontend/build/static/js/6899.0eaf36a8.chunk.js +2 -0
  182. rapidfireai/frontend/build/static/js/6899.0eaf36a8.chunk.js.LICENSE.txt +5 -0
  183. rapidfireai/frontend/build/static/js/6933.8b564944.chunk.js +1 -0
  184. rapidfireai/frontend/build/static/js/699.d0437920.js +1 -0
  185. rapidfireai/frontend/build/static/js/7076.4182f63a.chunk.js +1 -0
  186. rapidfireai/frontend/build/static/js/7186.42ad86d5.chunk.js +1 -0
  187. rapidfireai/frontend/build/static/js/7248.a46635fd.js +1 -0
  188. rapidfireai/frontend/build/static/js/725.6b15a14a.chunk.js +1 -0
  189. rapidfireai/frontend/build/static/js/7266.3575539d.chunk.js +1 -0
  190. rapidfireai/frontend/build/static/js/7270.0a1e84fc.chunk.js +2 -0
  191. rapidfireai/frontend/build/static/js/7270.0a1e84fc.chunk.js.LICENSE.txt +6 -0
  192. rapidfireai/frontend/build/static/js/7367.7120474f.chunk.js +1 -0
  193. rapidfireai/frontend/build/static/js/7436.8e226055.js +1 -0
  194. rapidfireai/frontend/build/static/js/7504.ef223844.chunk.js +1 -0
  195. rapidfireai/frontend/build/static/js/7603.ee049fe3.chunk.js +1 -0
  196. rapidfireai/frontend/build/static/js/7670.2835b49a.chunk.js +2 -0
  197. rapidfireai/frontend/build/static/js/7670.2835b49a.chunk.js.LICENSE.txt +6 -0
  198. rapidfireai/frontend/build/static/js/7721.7390b3cc.chunk.js +1 -0
  199. rapidfireai/frontend/build/static/js/7731.5796cced.chunk.js +1 -0
  200. rapidfireai/frontend/build/static/js/775.660a5deb.chunk.js +2 -0
  201. rapidfireai/frontend/build/static/js/775.660a5deb.chunk.js.LICENSE.txt +6 -0
  202. rapidfireai/frontend/build/static/js/7832.7976a3e4.chunk.js +1 -0
  203. rapidfireai/frontend/build/static/js/7844.72cc2e81.chunk.js +1 -0
  204. rapidfireai/frontend/build/static/js/7948.48eab032.js +1 -0
  205. rapidfireai/frontend/build/static/js/7972.085079d4.chunk.js +2 -0
  206. rapidfireai/frontend/build/static/js/7972.085079d4.chunk.js.LICENSE.txt +6 -0
  207. rapidfireai/frontend/build/static/js/8017.a9e7dc5a.chunk.js +1 -0
  208. rapidfireai/frontend/build/static/js/8023.75f1f3df.js +2 -0
  209. rapidfireai/frontend/build/static/js/8023.75f1f3df.js.LICENSE.txt +41 -0
  210. rapidfireai/frontend/build/static/js/8123.b69db974.js +1 -0
  211. rapidfireai/frontend/build/static/js/813.065a87e5.chunk.js +1 -0
  212. rapidfireai/frontend/build/static/js/819.2056f122.chunk.js +2 -0
  213. rapidfireai/frontend/build/static/js/819.2056f122.chunk.js.LICENSE.txt +6 -0
  214. rapidfireai/frontend/build/static/js/8262.04bc17d1.chunk.js +1 -0
  215. rapidfireai/frontend/build/static/js/8300.75adcc4f.chunk.js +1 -0
  216. rapidfireai/frontend/build/static/js/8336.b1d3e764.chunk.js +1 -0
  217. rapidfireai/frontend/build/static/js/8365.26cf64ea.chunk.js +1 -0
  218. rapidfireai/frontend/build/static/js/8398.8bca8e0e.chunk.js +2 -0
  219. rapidfireai/frontend/build/static/js/8398.8bca8e0e.chunk.js.LICENSE.txt +6 -0
  220. rapidfireai/frontend/build/static/js/847.33ceed50.chunk.js +2 -0
  221. rapidfireai/frontend/build/static/js/847.33ceed50.chunk.js.LICENSE.txt +6 -0
  222. rapidfireai/frontend/build/static/js/8486.8ec852a7.chunk.js +1 -0
  223. rapidfireai/frontend/build/static/js/8497.19378265.chunk.js +1 -0
  224. rapidfireai/frontend/build/static/js/8541.4c55c9f4.chunk.js +1 -0
  225. rapidfireai/frontend/build/static/js/8690.e305a804.chunk.js +2 -0
  226. rapidfireai/frontend/build/static/js/8690.e305a804.chunk.js.LICENSE.txt +6 -0
  227. rapidfireai/frontend/build/static/js/8712.a9445fe6.chunk.js +1 -0
  228. rapidfireai/frontend/build/static/js/8763.61761e08.js +1 -0
  229. rapidfireai/frontend/build/static/js/8823.baf9bffd.chunk.js +2 -0
  230. rapidfireai/frontend/build/static/js/8823.baf9bffd.chunk.js.LICENSE.txt +6 -0
  231. rapidfireai/frontend/build/static/js/8867.767462b7.chunk.js +1 -0
  232. rapidfireai/frontend/build/static/js/8953.c0f88dea.chunk.js +1 -0
  233. rapidfireai/frontend/build/static/js/8960.357cb1eb.chunk.js +2 -0
  234. rapidfireai/frontend/build/static/js/8960.357cb1eb.chunk.js.LICENSE.txt +6 -0
  235. rapidfireai/frontend/build/static/js/9.f4492795.chunk.js +2 -0
  236. rapidfireai/frontend/build/static/js/9.f4492795.chunk.js.LICENSE.txt +12 -0
  237. rapidfireai/frontend/build/static/js/9079.88a8d2a3.js +1 -0
  238. rapidfireai/frontend/build/static/js/9082.37c40520.chunk.js +10 -0
  239. rapidfireai/frontend/build/static/js/9133.90ae330d.js +2 -0
  240. rapidfireai/frontend/build/static/js/9133.90ae330d.js.LICENSE.txt +8 -0
  241. rapidfireai/frontend/build/static/js/9151.1ac359d5.js +2 -0
  242. rapidfireai/frontend/build/static/js/9151.1ac359d5.js.LICENSE.txt +8 -0
  243. rapidfireai/frontend/build/static/js/9168.027bf2fd.chunk.js +1 -0
  244. rapidfireai/frontend/build/static/js/9194.9c5cc548.chunk.js +10 -0
  245. rapidfireai/frontend/build/static/js/9244.026f4aee.chunk.js +1 -0
  246. rapidfireai/frontend/build/static/js/936.2e02d037.js +2 -0
  247. rapidfireai/frontend/build/static/js/936.2e02d037.js.LICENSE.txt +6 -0
  248. rapidfireai/frontend/build/static/js/9369.7d1a0a1d.chunk.js +1 -0
  249. rapidfireai/frontend/build/static/js/9427.7c8442e7.chunk.js +1 -0
  250. rapidfireai/frontend/build/static/js/944.55948859.chunk.js +1 -0
  251. rapidfireai/frontend/build/static/js/9499.c53a82da.js +2 -0
  252. rapidfireai/frontend/build/static/js/9499.c53a82da.js.LICENSE.txt +62 -0
  253. rapidfireai/frontend/build/static/js/9531.3ce05781.chunk.js +1 -0
  254. rapidfireai/frontend/build/static/js/9547.92fac952.chunk.js +2 -0
  255. rapidfireai/frontend/build/static/js/9547.92fac952.chunk.js.LICENSE.txt +6 -0
  256. rapidfireai/frontend/build/static/js/9620.b6e973a7.chunk.js +1 -0
  257. rapidfireai/frontend/build/static/js/9645.6fddfa65.chunk.js +1 -0
  258. rapidfireai/frontend/build/static/js/9669.d38dda6d.js +1 -0
  259. rapidfireai/frontend/build/static/js/9682.41b6b807.chunk.js +1 -0
  260. rapidfireai/frontend/build/static/js/9720.19d5ae76.chunk.js +2 -0
  261. rapidfireai/frontend/build/static/js/9720.19d5ae76.chunk.js.LICENSE.txt +23 -0
  262. rapidfireai/frontend/build/static/js/9723.d3c7fe9e.js +1 -0
  263. rapidfireai/frontend/build/static/js/9780.02a27630.chunk.js +10 -0
  264. rapidfireai/frontend/build/static/js/9808.d0ca9674.chunk.js +2 -0
  265. rapidfireai/frontend/build/static/js/9808.d0ca9674.chunk.js.LICENSE.txt +6 -0
  266. rapidfireai/frontend/build/static/js/9815.b8db3c5d.js +1 -0
  267. rapidfireai/frontend/build/static/js/9886.2940b53a.chunk.js +1 -0
  268. rapidfireai/frontend/build/static/js/main~1f912138.fa9d03b1.js +1 -0
  269. rapidfireai/frontend/build/static/js/main~43dd7041.2e00860d.js +1 -0
  270. rapidfireai/frontend/build/static/js/main~84781932.68deffff.js +1 -0
  271. rapidfireai/frontend/build/static/media/404-overflow.fad9a31861b0afba6f921ebb8e769688.svg +32 -0
  272. rapidfireai/frontend/build/static/media/RapidFire_Square_Bug.27ceb48296314a4bc0d4.png +0 -0
  273. rapidfireai/frontend/build/static/media/chart-bar.0fd4a63680fba840a7b69fbf07969f79.svg +7 -0
  274. rapidfireai/frontend/build/static/media/chart-contour.0d4b306f2669f3ad25375568935e3ce3.svg +5 -0
  275. rapidfireai/frontend/build/static/media/chart-difference.16174216d6f3b7c24f40e3541fe0ca2c.svg +20 -0
  276. rapidfireai/frontend/build/static/media/chart-image.cc434c4dc50780966344e2385a15f8fe.svg +6 -0
  277. rapidfireai/frontend/build/static/media/chart-line.0adaa2036bb4eb5956db6d0c7e925a3d.svg +4 -0
  278. rapidfireai/frontend/build/static/media/chart-parallel.da7dedf539b2af4b654d377c679173e4.svg +7 -0
  279. rapidfireai/frontend/build/static/media/chart-scatter.69118d0023a6ff3973f7fa913834ac47.svg +9 -0
  280. rapidfireai/frontend/build/static/media/default-error.f246ddf367c6fbd67942e5a13382a7f1.svg +26 -0
  281. rapidfireai/frontend/build/static/media/fontawesome-webfont.1e59d2330b4c6deb84b3.ttf +0 -0
  282. rapidfireai/frontend/build/static/media/fontawesome-webfont.20fd1704ea223900efa9.woff2 +0 -0
  283. rapidfireai/frontend/build/static/media/fontawesome-webfont.8b43027f47b20503057d.eot +0 -0
  284. rapidfireai/frontend/build/static/media/fontawesome-webfont.c1e38fd9e0e74ba58f7a.svg +2671 -0
  285. rapidfireai/frontend/build/static/media/fontawesome-webfont.f691f37e57f04c152e23.woff +0 -0
  286. rapidfireai/frontend/build/static/media/icon-visible-fill.8d34cd35303828fdfc15154f5536e63b.svg +7 -0
  287. rapidfireai/frontend/build/static/media/no-experiments.0e4f4a114ef73e7d81c09474aba64b6c.svg +22 -0
  288. rapidfireai/frontend/build/static/media/parallel-chart-placeholder.234ef0c5b220ef2a5a6fa5bafff173f7.svg +16 -0
  289. rapidfireai/frontend/build/static/media/permission-denied-lock.16036747d57cd663d7df223781a447b2.svg +14 -0
  290. rapidfireai/frontend/build/static/media/promo-modal-content.e3b2c6c568ac192b9bec54b838b54850.svg +30 -0
  291. rapidfireai/frontend/build/static/media/registered-model-grey-ok.8274b58d39504c8d1b8c358aa1c9aa35.svg +23 -0
  292. rapidfireai/frontend/build/static/media/warning.290a3b14118933547965e91ea61c5a61.svg +3 -0
  293. rapidfireai/frontend/proxy_middleware.py +233 -0
  294. rapidfireai/frontend/server.py +25 -0
  295. rapidfireai/ml/__init__.py +0 -0
  296. rapidfireai/ml/callbacks.py +176 -0
  297. rapidfireai/ml/checkpoint_utils.py +540 -0
  298. rapidfireai/ml/trainer.py +309 -0
  299. rapidfireai/start.sh +634 -0
  300. rapidfireai/utils/__init__.py +0 -0
  301. rapidfireai/utils/automl_utils.py +51 -0
  302. rapidfireai/utils/constants.py +141 -0
  303. rapidfireai/utils/datapaths.py +69 -0
  304. rapidfireai/utils/exceptions.py +82 -0
  305. rapidfireai/utils/experiment_utils.py +370 -0
  306. rapidfireai/utils/logging.py +87 -0
  307. rapidfireai/utils/mlflow_manager.py +121 -0
  308. rapidfireai/utils/serialize.py +15 -0
  309. rapidfireai/utils/shm_manager.py +469 -0
  310. rapidfireai/utils/trainer_config.py +23 -0
  311. rapidfireai/utils/worker_manager.py +219 -0
  312. rapidfireai/version.py +6 -0
  313. rapidfireai-0.9.10.dist-info/METADATA +247 -0
  314. rapidfireai-0.9.10.dist-info/RECORD +318 -0
  315. rapidfireai-0.9.10.dist-info/entry_points.txt +2 -0
  316. rapidfireai-0.0.1.dist-info/METADATA +0 -37
  317. rapidfireai-0.0.1.dist-info/RECORD +0 -6
  318. {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.10.dist-info}/WHEEL +0 -0
  319. {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.10.dist-info}/licenses/LICENSE +0 -0
  320. {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.10.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,694 @@
1
+ """This module contains the RfDb class which is responsible for handling the database operations."""
2
+
3
+ import json
4
+ import os
5
+ import sqlite3
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ from rapidfireai.db.db_interface import DatabaseInterface
10
+ from rapidfireai.utils.constants import (
11
+ ControllerTask,
12
+ ExperimentStatus,
13
+ ExperimentTask,
14
+ RunEndedBy,
15
+ RunSource,
16
+ RunStatus,
17
+ TaskStatus,
18
+ WorkerTask,
19
+ )
20
+ from rapidfireai.utils.exceptions import DBException
21
+ from rapidfireai.utils.serialize import decode_db_payload, encode_payload
22
+
23
+ # TODO: add custom exceptions like - RunNotFoundError, ExperimentNotFoundError, ICOpsOnKilledRuns, etc
24
+
25
+
26
+ class RfDb:
27
+ """Class to handle the database operations"""
28
+
29
+ def __init__(self):
30
+ self.db: DatabaseInterface = DatabaseInterface()
31
+
32
+ def create_tables(self):
33
+ """Create the tables in the database"""
34
+ try:
35
+ # Get the directory where this file is located
36
+ current_dir = os.path.dirname(os.path.abspath(__file__))
37
+ tables_file = os.path.join(current_dir, "tables.sql")
38
+
39
+ # First check if tables exist
40
+ table_check = self.db.conn.execute(
41
+ "SELECT name FROM sqlite_master WHERE type='table' AND name='experiments'"
42
+ ).fetchone()
43
+
44
+ if table_check is None:
45
+ # Tables don't exist, create them
46
+ with open(tables_file, encoding="utf-8") as f:
47
+ sql_content = f.read()
48
+ _ = self.db.conn.executescript(sql_content)
49
+
50
+ except FileNotFoundError as e:
51
+ raise DBException(f"tables.sql file not found at {tables_file}") from e
52
+ except sqlite3.Error as e:
53
+ raise DBException(f"Failed to create tables: {e}") from e
54
+ except Exception as e:
55
+ raise DBException(f"Unexpected error creating tables: {e}") from e
56
+
57
+ def close(self):
58
+ """Close the database connection"""
59
+ self.db.close()
60
+
61
+ def reset_all_tables(self, experiments_table: bool = False) -> None:
62
+ """Truncate tables when an experiment is ended"""
63
+ # ordering based on foreign key constraints
64
+ tables = [
65
+ "controller_progress",
66
+ "worker_progress",
67
+ "worker_task",
68
+ "interactive_control",
69
+ "runs",
70
+ ]
71
+
72
+ if experiments_table:
73
+ tables.append("experiments")
74
+
75
+ for table in tables:
76
+ query = f"DELETE FROM {table};"
77
+ self.db.execute(query, commit=True)
78
+
79
+ # Reset auto-increment indices to start from 1
80
+ for table in tables:
81
+ query = "DELETE FROM sqlite_sequence WHERE name = ?;"
82
+ self.db.execute(query, (table,), commit=True)
83
+
84
+ def reset_experiment_states(self) -> None:
85
+ """Reset the experiment states when a running task is cancelled"""
86
+
87
+ # mark all scheduled and in-progress worker tasks as failed
88
+ query = """
89
+ UPDATE worker_task
90
+ SET status = ?
91
+ WHERE status = ? OR status = ?
92
+ """
93
+ self.db.execute(
94
+ query, (TaskStatus.FAILED.value, TaskStatus.IN_PROGRESS.value, TaskStatus.SCHEDULED.value), commit=True
95
+ )
96
+
97
+ # mark ongoing and new Runs as failed
98
+ all_runs = self.get_runs_by_status([RunStatus.ONGOING, RunStatus.NEW]).keys()
99
+ for run_id in all_runs:
100
+ self.set_run_status(run_id, RunStatus.FAILED)
101
+
102
+ # reset all interactive control tasks
103
+ all_ic_ops_tasks = self.get_scheduled_ic_ops_tasks()
104
+ for task in all_ic_ops_tasks:
105
+ self.set_ic_ops_task_status(task["task_id"], TaskStatus.SKIPPED)
106
+
107
+ # reset all progress tables
108
+ for table in ["controller_progress", "worker_progress"]:
109
+ query = f"DELETE FROM {table};"
110
+ self.db.execute(query, commit=True)
111
+
112
+ # Experiments Table
113
+ def create_experiment(
114
+ self,
115
+ experiment_name: str,
116
+ mlflow_experiment_id: str,
117
+ config_options: dict[str, Any],
118
+ ) -> int:
119
+ """Create a new experiment"""
120
+ query = """
121
+ INSERT INTO experiments (experiment_name, mlflow_experiment_id, config_options,
122
+ status, current_task, error)
123
+ VALUES (?, ?, ?, ?, ?, ?)
124
+ RETURNING experiment_id
125
+ """
126
+
127
+ result = self.db.execute(
128
+ query,
129
+ (
130
+ experiment_name,
131
+ mlflow_experiment_id,
132
+ encode_payload(config_options),
133
+ ExperimentStatus.RUNNING.value,
134
+ ExperimentTask.IDLE.value,
135
+ "",
136
+ ),
137
+ commit=True,
138
+ fetch=True,
139
+ )
140
+ if result:
141
+ # run db optimizer every time an experiment is created
142
+ self.db.optimize_periodically()
143
+
144
+ # return experiment_id
145
+ return result[0][0]
146
+ raise DBException("Failed to create experiment")
147
+
148
+ def get_running_experiment(self) -> dict[str, Any]:
149
+ """Get an experiment's details by its ID"""
150
+ query = """
151
+ SELECT experiment_id, experiment_name, status, error, mlflow_experiment_id, config_options
152
+ FROM experiments
153
+ WHERE status = ?
154
+ ORDER BY experiment_id DESC
155
+ LIMIT 1
156
+ """
157
+ experiment_details = self.db.execute(query, (ExperimentStatus.RUNNING.value,), fetch=True)
158
+
159
+ if experiment_details:
160
+ experiment_details = experiment_details[0]
161
+ experiment_details = {
162
+ "experiment_id": experiment_details[0],
163
+ "experiment_name": experiment_details[1],
164
+ "status": ExperimentStatus(experiment_details[2]),
165
+ "error": experiment_details[3],
166
+ "mlflow_experiment_id": experiment_details[4],
167
+ "config_options": decode_db_payload(experiment_details[5]),
168
+ }
169
+ return experiment_details
170
+ raise DBException("No running experiment found")
171
+
172
+ def get_experiment_status(self) -> ExperimentStatus | None:
173
+ """Get the status of an experiment"""
174
+ query = """
175
+ SELECT status
176
+ FROM experiments
177
+ ORDER BY experiment_id DESC
178
+ LIMIT 1
179
+ """
180
+ status = self.db.execute(query, fetch=True)
181
+
182
+ if status:
183
+ return ExperimentStatus(status[0][0])
184
+ raise DBException("No experiment status found")
185
+
186
+ def set_experiment_status(self, experiment_id: int, status: ExperimentStatus) -> None:
187
+ """Set the status of an experiment"""
188
+ query = """
189
+ UPDATE experiments
190
+ SET status = ?
191
+ WHERE experiment_id = ?
192
+ """
193
+ self.db.execute(query, (status.value, experiment_id), commit=True)
194
+
195
+ def set_experiment_error(self, error: str) -> None:
196
+ """Set the error message of an experiment"""
197
+ query = """
198
+ UPDATE experiments
199
+ SET error = ?
200
+ WHERE status = ?
201
+ """
202
+ self.db.execute(query, (error, ExperimentStatus.RUNNING.value), commit=True)
203
+
204
+ def get_experiment_error(self) -> str:
205
+ """Get the error message of an experiment"""
206
+ query = """
207
+ SELECT error
208
+ FROM experiments
209
+ ORDER BY experiment_id DESC
210
+ LIMIT 1
211
+ """
212
+ error = self.db.execute(query, fetch=True)
213
+
214
+ if error:
215
+ return error[0][0]
216
+ else:
217
+ return ""
218
+
219
+ def set_experiment_current_task(self, task: ExperimentTask) -> None:
220
+ """Set the current task of an experiment"""
221
+ query = """
222
+ UPDATE experiments
223
+ SET current_task = ?
224
+ WHERE status = ?
225
+ """
226
+ self.db.execute(query, (task.value, ExperimentStatus.RUNNING.value), commit=True)
227
+
228
+ def get_experiment_current_task(self) -> ExperimentTask:
229
+ """Get the current task of an experiment"""
230
+ query = """
231
+ SELECT current_task
232
+ FROM experiments
233
+ WHERE status = ?
234
+ ORDER BY experiment_id DESC
235
+ LIMIT 1
236
+ """
237
+ task = self.db.execute(query, (ExperimentStatus.RUNNING.value,), fetch=True)
238
+
239
+ if task:
240
+ return ExperimentTask(task[0][0])
241
+ raise DBException("No running experiment found")
242
+
243
+ def get_all_experiment_names(self) -> list[str]:
244
+ """Get all experiment names"""
245
+ query = """
246
+ SELECT experiment_name
247
+ FROM experiments
248
+ """
249
+ experiment_names = self.db.execute(query, fetch=True)
250
+
251
+ if experiment_names:
252
+ return [experiment[0] for experiment in experiment_names]
253
+ else:
254
+ return []
255
+
256
+ def get_experiments_path(self, experiment_name: str) -> Path:
257
+ """Get the experiments path for a given experiment name"""
258
+ query = """
259
+ SELECT config_options
260
+ FROM experiments
261
+ WHERE experiment_name = ?
262
+ """
263
+ config_options = self.db.execute(query, (experiment_name,), fetch=True)
264
+ if config_options:
265
+ config_dict = decode_db_payload(config_options[0][0])
266
+ return Path(config_dict["experiments_path"])
267
+ raise DBException("Experiments path not found for running experiment")
268
+
269
+ # Runs Table
270
+ def create_run(
271
+ self,
272
+ config_leaf: dict[str, Any],
273
+ status: RunStatus,
274
+ mlflow_run_id: str | None = None,
275
+ flattened_config: dict[str, Any] | None = None,
276
+ completed_steps: int = 0,
277
+ total_steps: int = 0,
278
+ start_chunk_id: int = 0,
279
+ num_chunks_visited_curr_epoch: int = 0,
280
+ num_epochs_completed: int = 0,
281
+ error: str = "",
282
+ source: RunSource | None = None,
283
+ ended_by: RunEndedBy | None = None,
284
+ warm_started_from: int | None = None,
285
+ ) -> int:
286
+ """Create a new run"""
287
+ query = """
288
+ INSERT INTO runs (status, mlflow_run_id, flattened_config, config_leaf,
289
+ completed_steps, total_steps, start_chunk_id, num_chunks_visited_curr_epoch, num_epochs_completed, error, source, ended_by, warm_started_from)
290
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
291
+ """
292
+ self.db.execute(
293
+ query,
294
+ (
295
+ status.value,
296
+ mlflow_run_id,
297
+ json.dumps(flattened_config) if flattened_config else "{}",
298
+ encode_payload(config_leaf) if config_leaf else "{}",
299
+ completed_steps,
300
+ total_steps,
301
+ start_chunk_id,
302
+ num_chunks_visited_curr_epoch,
303
+ num_epochs_completed,
304
+ error,
305
+ source.value if source else "",
306
+ ended_by.value if ended_by else "",
307
+ warm_started_from,
308
+ ),
309
+ commit=True,
310
+ )
311
+ result = self.db.execute("SELECT last_insert_rowid()", fetch=True)
312
+ if result:
313
+ return result[0][0]
314
+ raise DBException("Failed to create run")
315
+
316
+ def set_run_details(
317
+ self,
318
+ run_id: int,
319
+ status: RunStatus | None = None,
320
+ mlflow_run_id: str | None = None,
321
+ flattened_config: dict[str, Any] | None = None,
322
+ config_leaf: dict[str, Any] | None = None,
323
+ completed_steps: int | None = None,
324
+ total_steps: int | None = None,
325
+ start_chunk_id: int | None = None,
326
+ num_chunks_visited_curr_epoch: int | None = None,
327
+ num_epochs_completed: int | None = None,
328
+ error: str | None = None,
329
+ source: RunSource | None = None,
330
+ ended_by: RunEndedBy | None = None,
331
+ warm_started_from: int | None = None,
332
+ ) -> None:
333
+ """Set the details of an existing run"""
334
+ # Initialize a dictionary to hold the column-value pairs
335
+ columns = {
336
+ "status": status.value if status else None,
337
+ "mlflow_run_id": mlflow_run_id,
338
+ "flattened_config": json.dumps(flattened_config) if flattened_config else None,
339
+ "config_leaf": encode_payload(config_leaf) if config_leaf else None,
340
+ "completed_steps": completed_steps,
341
+ "total_steps": total_steps,
342
+ "start_chunk_id": start_chunk_id,
343
+ "num_chunks_visited_curr_epoch": num_chunks_visited_curr_epoch,
344
+ "num_epochs_completed": num_epochs_completed,
345
+ "error": error,
346
+ "source": source.value if source else None,
347
+ "ended_by": ended_by.value if ended_by else None,
348
+ "warm_started_from": warm_started_from,
349
+ }
350
+
351
+ # Filter out None values
352
+ columns = {k: v for k, v in columns.items() if v is not None}
353
+
354
+ # If no columns to update, return early
355
+ if not columns:
356
+ return
357
+
358
+ # Construct the query parts
359
+ query_parts = [f"{col} = ?" for col in columns]
360
+ values = list(columns.values())
361
+
362
+ # Ensure run_id is always included
363
+ values.append(run_id)
364
+
365
+ # Construct the final query
366
+ query = f"UPDATE runs SET {', '.join(query_parts)} WHERE run_id = ?"
367
+
368
+ # Execute the query
369
+ self.db.execute(query, tuple(values), commit=True)
370
+
371
+ def get_run(self, run_id: int) -> dict[str, Any]:
372
+ """Get a run's details"""
373
+ query = """
374
+ SELECT status, mlflow_run_id, flattened_config, config_leaf, completed_steps, total_steps, start_chunk_id,
375
+ num_chunks_visited_curr_epoch, num_epochs_completed, error, source, ended_by, warm_started_from
376
+ FROM runs
377
+ WHERE run_id = ?
378
+ """
379
+ run_details = self.db.execute(query, (run_id,), fetch=True)
380
+
381
+ if run_details:
382
+ run_details = run_details[0]
383
+ formatted_details = {
384
+ "status": RunStatus(run_details[0]),
385
+ "mlflow_run_id": run_details[1],
386
+ "flattened_config": json.loads(run_details[2]),
387
+ "config_leaf": decode_db_payload(run_details[3]) if run_details[3] and run_details[3] != "{}" else {},
388
+ "completed_steps": run_details[4],
389
+ "total_steps": run_details[5],
390
+ "start_chunk_id": run_details[6],
391
+ "num_chunks_visited_curr_epoch": run_details[7],
392
+ "num_epochs_completed": run_details[8],
393
+ "error": run_details[9],
394
+ "source": RunSource(run_details[10]) if run_details[10] else None,
395
+ "ended_by": RunEndedBy(run_details[11]) if run_details[11] else None,
396
+ "warm_started_from": run_details[12],
397
+ }
398
+ return formatted_details
399
+ raise DBException("No run found")
400
+
401
+ def get_runs_by_status(self, statuses: list[RunStatus]) -> dict[int, dict[str, Any]]:
402
+ """Get all runs by statuses"""
403
+ if not statuses:
404
+ return {}
405
+
406
+ # Create placeholders for SQL IN clause
407
+ placeholders = ",".join(["?"] * len(statuses))
408
+ query = f"""
409
+ SELECT run_id, status, mlflow_run_id, flattened_config, config_leaf, completed_steps, total_steps,
410
+ start_chunk_id, num_chunks_visited_curr_epoch, num_epochs_completed, error, source, ended_by, warm_started_from
411
+ FROM runs
412
+ WHERE status IN ({placeholders})
413
+ """
414
+ # Extract status values for the query parameters
415
+ status_values = [status.value for status in statuses]
416
+ run_details = self.db.execute(query, status_values, fetch=True)
417
+ formatted_details: dict[int, dict[str, Any]] = {}
418
+ if run_details:
419
+ for run in run_details:
420
+ formatted_details[run[0]] = {
421
+ "status": RunStatus(run[1]),
422
+ "mlflow_run_id": run[2],
423
+ "flattened_config": json.loads(run[3]),
424
+ "config_leaf": decode_db_payload(run[4]) if run[4] and run[4] != "{}" else {},
425
+ "completed_steps": run[5],
426
+ "total_steps": run[6],
427
+ "start_chunk_id": run[7],
428
+ "num_chunks_visited_curr_epoch": run[8],
429
+ "num_epochs_completed": run[9],
430
+ "error": run[10],
431
+ "source": RunSource(run[11]) if run[11] else None,
432
+ "ended_by": RunEndedBy(run[12]) if run[12] else None,
433
+ "warm_started_from": run[13],
434
+ }
435
+ return formatted_details
436
+
437
+ def get_all_runs(self) -> dict[int, dict[str, Any]]:
438
+ """Get all runs for UI display (ignore all complex fields)"""
439
+ query = """
440
+ SELECT run_id, status, mlflow_run_id, flattened_config, config_leaf, completed_steps, total_steps,
441
+ start_chunk_id, num_chunks_visited_curr_epoch, num_epochs_completed, error, source, ended_by, warm_started_from
442
+ FROM runs
443
+ """
444
+ run_details = self.db.execute(query, fetch=True)
445
+
446
+ formatted_details: dict[int, dict[str, Any]] = {}
447
+ if run_details:
448
+ for run in run_details:
449
+ formatted_details[run[0]] = {
450
+ "status": RunStatus(run[1]),
451
+ "mlflow_run_id": run[2],
452
+ "flattened_config": json.loads(run[3]),
453
+ "config_leaf": decode_db_payload(run[4]) if run[4] and run[4] != "{}" else {},
454
+ "completed_steps": run[5],
455
+ "total_steps": run[6],
456
+ "start_chunk_id": run[7],
457
+ "num_chunks_visited_curr_epoch": run[8],
458
+ "num_epochs_completed": run[9],
459
+ "error": run[10],
460
+ "source": RunSource(run[11]) if run[11] else None,
461
+ "ended_by": RunEndedBy(run[12]) if run[12] else None,
462
+ "warm_started_from": run[13],
463
+ }
464
+ return formatted_details
465
+
466
+ def set_run_status(self, run_id: int, status: RunStatus) -> None:
467
+ """Set the status of a run"""
468
+ query = """
469
+ UPDATE runs
470
+ SET status = ?
471
+ WHERE run_id = ?
472
+ """
473
+ self.db.execute(query, (status.value, run_id), commit=True)
474
+
475
+ def set_completed_steps(self, run_id: int, completed_steps: int) -> None:
476
+ """Set the current completed steps for a run"""
477
+ query = """
478
+ UPDATE runs
479
+ SET completed_steps = ?
480
+ WHERE run_id = ?
481
+ """
482
+ self.db.execute(query, (completed_steps, run_id), commit=True)
483
+
484
+ def get_completed_steps(self, run_id: int) -> int:
485
+ """Get the current completed steps for a run"""
486
+ query = """
487
+ SELECT completed_steps
488
+ FROM runs
489
+ WHERE run_id = ?
490
+ """
491
+ completed_steps = self.db.execute(query, (run_id,), fetch=True)
492
+ if completed_steps:
493
+ return completed_steps[0][0]
494
+ raise DBException("No completed steps found")
495
+
496
+ # Interactive Control Table
497
+ def create_ic_ops_task(self, run_id: int, ic_op: ControllerTask, config_leaf: dict[str, Any]) -> int:
498
+ """Create a new interactive control task"""
499
+ query = """
500
+ INSERT INTO interactive_control (run_id, ic_op, config_leaf, status)
501
+ VALUES (?, ?, ?, ?)
502
+ RETURNING task_id
503
+ """
504
+ config_leaf_str = encode_payload(config_leaf) if config_leaf else "{}"
505
+ result = self.db.execute(
506
+ query,
507
+ (run_id, ic_op.value, config_leaf_str, TaskStatus.SCHEDULED.value),
508
+ commit=True,
509
+ fetch=True,
510
+ )
511
+ if result:
512
+ return result[0][0]
513
+ raise DBException("Failed to create interactive control task")
514
+
515
+ def get_scheduled_ic_ops_tasks(self) -> list[dict[str, Any]]:
516
+ """Get all scheduled interactive control operations"""
517
+ query = """
518
+ SELECT task_id, run_id, ic_op, config_leaf
519
+ FROM interactive_control
520
+ WHERE status = ?
521
+ """
522
+ tasks = self.db.execute(query, (TaskStatus.SCHEDULED.value,), fetch=True)
523
+ if not tasks:
524
+ return []
525
+ return [
526
+ {
527
+ "task_id": task[0],
528
+ "run_id": task[1],
529
+ "ic_op": ControllerTask(task[2]),
530
+ "config_leaf": decode_db_payload(task[3]),
531
+ }
532
+ for task in tasks
533
+ ]
534
+
535
+ def set_ic_ops_task_status(self, task_id: int, status: TaskStatus) -> None:
536
+ """Set the status of an interactive control operation"""
537
+ query = """
538
+ UPDATE interactive_control
539
+ SET status = ?
540
+ WHERE task_id = ?
541
+ """
542
+ self.db.execute(query, (status.value, task_id), commit=True)
543
+
544
+ # Worker Task Table
545
+ def create_worker_task(
546
+ self,
547
+ worker_id: int,
548
+ task_type: WorkerTask,
549
+ status: TaskStatus,
550
+ run_id: int,
551
+ chunk_id: int = -1,
552
+ config_options: dict[str, Any] | None = None,
553
+ ) -> int:
554
+ """Create a worker task"""
555
+
556
+ query = """
557
+ INSERT INTO worker_task (worker_id, task_type, status, run_id, chunk_id, config_options)
558
+ VALUES (?, ?, ?, ?, ?, ?)
559
+ """
560
+ config_options_str = encode_payload(config_options) if config_options else "{}"
561
+ self.db.execute(
562
+ query,
563
+ (
564
+ worker_id,
565
+ task_type.value,
566
+ status.value,
567
+ run_id,
568
+ chunk_id,
569
+ config_options_str,
570
+ ),
571
+ commit=True,
572
+ )
573
+ result = self.db.execute("SELECT last_insert_rowid()", fetch=True)
574
+ if result:
575
+ return result[0][0]
576
+ raise DBException("Failed to create worker task")
577
+
578
+ def get_all_worker_tasks(self) -> dict[int, dict[str, Any]]:
579
+ """Get the latest task of each worker"""
580
+ query = """
581
+ SELECT worker_id, task_id, task_type, status, run_id, chunk_id, config_options
582
+ FROM worker_task wt1
583
+ WHERE task_id = (
584
+ SELECT MAX(task_id)
585
+ FROM worker_task wt2
586
+ WHERE wt2.worker_id = wt1.worker_id
587
+ )
588
+ """
589
+ task_details = self.db.execute(query, fetch=True)
590
+
591
+ formatted_details: dict[int, dict[str, Any]] = {}
592
+ if task_details:
593
+ for task in task_details:
594
+ formatted_details[task[0]] = {
595
+ "task_id": task[1],
596
+ "task_type": WorkerTask(task[2]),
597
+ "status": TaskStatus(task[3]),
598
+ "run_id": task[4],
599
+ "chunk_id": task[5],
600
+ "config_options": decode_db_payload(task[6]) if task[6] and task[6] != "{}" else {},
601
+ }
602
+ return formatted_details
603
+
604
+ def get_worker_scheduled_task(self, worker_id: int) -> dict[str, Any]:
605
+ """Get the latest scheduled task for a worker"""
606
+ query = """
607
+ SELECT task_id, task_type, run_id, chunk_id, config_options
608
+ FROM worker_task
609
+ WHERE worker_id = ? AND status = ?
610
+ ORDER BY task_id DESC
611
+ LIMIT 1
612
+ """
613
+ task_details = self.db.execute(query, (worker_id, TaskStatus.SCHEDULED.value), fetch=True)
614
+
615
+ if task_details:
616
+ task_details = task_details[0]
617
+ formatted_details = {
618
+ "task_id": task_details[0],
619
+ "task_type": WorkerTask(task_details[1]),
620
+ "run_id": task_details[2],
621
+ "chunk_id": task_details[3],
622
+ "config_options": decode_db_payload(task_details[4])
623
+ if task_details[4] and task_details[4] != "{}"
624
+ else {},
625
+ }
626
+ return formatted_details
627
+ return {}
628
+
629
+ def set_worker_task_status(self, worker_id: int, status: TaskStatus) -> None:
630
+ """Set the status of the latest task of a worker"""
631
+ query = """
632
+ UPDATE worker_task
633
+ SET status = ?
634
+ WHERE task_id = (
635
+ SELECT task_id
636
+ FROM worker_task
637
+ WHERE worker_id = ?
638
+ ORDER BY task_id DESC
639
+ LIMIT 1
640
+ )
641
+ """
642
+ self.db.execute(query, (status.value, worker_id), commit=True)
643
+
644
+ # Train Controller Progress Table
645
+ def set_controller_progress(self, run_id: int, progress: float) -> None:
646
+ """Set the Train progress for a Train Controller"""
647
+ query = """
648
+ INSERT INTO controller_progress (run_id, progress)
649
+ VALUES (?, ?)
650
+ ON CONFLICT (run_id)
651
+ DO UPDATE SET
652
+ progress = EXCLUDED.progress;
653
+ """
654
+ progress_rounded = round(progress, 2)
655
+ self.db.execute(query, (run_id, progress_rounded), commit=True)
656
+
657
+ def get_controller_progress(self, run_id: int) -> float:
658
+ """Get the train progress for a Controller"""
659
+ query = """
660
+ SELECT progress
661
+ FROM controller_progress
662
+ WHERE run_id = ?
663
+ """
664
+ progress_details = self.db.execute(query, (run_id,), fetch=True)
665
+
666
+ if progress_details:
667
+ return progress_details[0][0]
668
+ return 0.0
669
+
670
+ # Train Worker Progress Table
671
+ def set_worker_progress(self, run_id: int, subchunk_progress: float) -> None:
672
+ """Set the progress of a Worker for training"""
673
+ query = """
674
+ INSERT INTO worker_progress (run_id, subchunk_progress)
675
+ VALUES (?, ?)
676
+ ON CONFLICT (run_id)
677
+ DO UPDATE SET
678
+ subchunk_progress = EXCLUDED.subchunk_progress;
679
+ """
680
+ progress_rounded = round(subchunk_progress, 2)
681
+ self.db.execute(query, (run_id, progress_rounded), commit=True)
682
+
683
+ def get_worker_progress(self, run_id: int) -> float:
684
+ """Get the progress of a Worker for training"""
685
+ query = """
686
+ SELECT subchunk_progress
687
+ FROM worker_progress
688
+ WHERE run_id = ?
689
+ """
690
+ progress_details = self.db.execute(query, (run_id,), fetch=True)
691
+
692
+ if progress_details:
693
+ return progress_details[0][0]
694
+ return 0.0