rapidfireai 0.0.1__py3-none-any.whl → 0.9.9__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.9.dist-info/METADATA +242 -0
  314. rapidfireai-0.9.9.dist-info/RECORD +318 -0
  315. rapidfireai-0.9.9.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.9.dist-info}/WHEEL +0 -0
  319. {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.9.dist-info}/licenses/LICENSE +0 -0
  320. {rapidfireai-0.0.1.dist-info → rapidfireai-0.9.9.dist-info}/top_level.txt +0 -0
rapidfireai/cli.py ADDED
@@ -0,0 +1,380 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Command-line interface for RapidFire AI
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import subprocess
9
+ import argparse
10
+ import platform
11
+ import shutil
12
+ import re
13
+ from pathlib import Path
14
+ from .version import __version__
15
+
16
+
17
+ def get_script_path():
18
+ """Get the path to the start.sh script."""
19
+ # Get the directory where this package is installed
20
+ package_dir = Path(__file__).parent
21
+ script_path = package_dir / "start.sh"
22
+
23
+ if not script_path.exists():
24
+ # Fallback: try to find it relative to the current working directory
25
+ script_path = Path.cwd() / "rapidfireai" / "start.sh"
26
+ if not script_path.exists():
27
+ raise FileNotFoundError(f"Could not find start.sh script at {script_path}")
28
+
29
+ return script_path
30
+
31
+
32
+ def run_script(args):
33
+ """Run the start.sh script with the given arguments."""
34
+ script_path = get_script_path()
35
+
36
+ # Make sure the script is executable
37
+ if not os.access(script_path, os.X_OK):
38
+ os.chmod(script_path, 0o755)
39
+
40
+ # Run the script with the provided arguments
41
+ try:
42
+ result = subprocess.run([str(script_path)] + args, check=True)
43
+ return result.returncode
44
+ except subprocess.CalledProcessError as e:
45
+ print(f"Error running start.sh: {e}", file=sys.stderr)
46
+ return e.returncode
47
+ except FileNotFoundError:
48
+ print(f"Error: start.sh script not found at {script_path}", file=sys.stderr)
49
+ return 1
50
+
51
+
52
+ def get_python_info():
53
+ """Get comprehensive Python information."""
54
+ info = {}
55
+
56
+ # Python version and implementation
57
+ info['version'] = sys.version
58
+ info['implementation'] = platform.python_implementation()
59
+ info['executable'] = sys.executable
60
+
61
+ # Environment information
62
+ info['conda_env'] = os.environ.get('CONDA_DEFAULT_ENV', 'none')
63
+ info['venv'] = 'yes' if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) else 'no'
64
+
65
+ return info
66
+
67
+
68
+ def get_pip_packages():
69
+ """Get list of installed pip packages."""
70
+ try:
71
+ result = subprocess.run([sys.executable, '-m', 'pip', 'list'],
72
+ capture_output=True, text=True, check=True)
73
+ return result.stdout
74
+ except (subprocess.CalledProcessError, FileNotFoundError):
75
+ return "Failed to get pip packages"
76
+
77
+
78
+ def get_gpu_info():
79
+ """Get comprehensive GPU and CUDA information."""
80
+ info = {}
81
+
82
+ # Check for nvidia-smi
83
+ nvidia_smi_path = shutil.which('nvidia-smi')
84
+ info['nvidia_smi'] = 'found' if nvidia_smi_path else 'not found'
85
+
86
+ if nvidia_smi_path:
87
+ try:
88
+ # Get driver and CUDA runtime version from the full nvidia-smi output
89
+ result = subprocess.run(['nvidia-smi'],
90
+ capture_output=True, text=True, check=True)
91
+ if result.stdout.strip():
92
+ lines = result.stdout.strip().split('\n')
93
+ # Look for the header line that contains CUDA version
94
+ for line in lines:
95
+ if 'CUDA Version:' in line:
96
+ # Extract CUDA version from line like "NVIDIA-SMI 535.183.06 Driver Version: 535.183.06 CUDA Version: 12.2"
97
+ cuda_version = line.split('CUDA Version:')[1].split()[0]
98
+ info['cuda_runtime'] = cuda_version
99
+ # Also extract driver version from the same line
100
+ if 'Driver Version:' in line:
101
+ driver_version = line.split('Driver Version:')[1].split('CUDA Version:')[0].strip()
102
+ info['driver_version'] = driver_version
103
+ break
104
+ else:
105
+ info['driver_version'] = 'unknown'
106
+ info['cuda_runtime'] = 'unknown'
107
+ except (subprocess.CalledProcessError, ValueError):
108
+ info['driver_version'] = 'unknown'
109
+ info['cuda_runtime'] = 'unknown'
110
+
111
+ # Get GPU count, models, and VRAM
112
+ try:
113
+ result = subprocess.run(['nvidia-smi', '--query-gpu=count,name,memory.total', '--format=csv,noheader,nounits'],
114
+ capture_output=True, text=True, check=True)
115
+ if result.stdout.strip():
116
+ lines = result.stdout.strip().split('\n')
117
+ if lines:
118
+ count, name, memory = lines[0].split(', ')
119
+ info['gpu_count'] = int(count)
120
+ info['gpu_model'] = name.strip()
121
+ # Convert memory from MiB to GB
122
+ memory_mib = int(memory.split()[0])
123
+ memory_gb = memory_mib / 1024
124
+ info['gpu_memory_gb'] = f"{memory_gb:.1f}"
125
+
126
+ # Get detailed info for multiple GPUs if present
127
+ if info['gpu_count'] > 1:
128
+ info['gpu_details'] = []
129
+ for line in lines:
130
+ count, name, memory = line.split(', ')
131
+ memory_mib = int(memory.split()[0])
132
+ memory_gb = memory_mib / 1024
133
+ info['gpu_details'].append({
134
+ 'name': name.strip(),
135
+ 'memory_gb': f"{memory_gb:.1f}"
136
+ })
137
+ except (subprocess.CalledProcessError, ValueError):
138
+ info['gpu_count'] = 0
139
+ info['gpu_model'] = 'unknown'
140
+ info['gpu_memory_gb'] = 'unknown'
141
+ else:
142
+ info['driver_version'] = 'N/A'
143
+ info['cuda_runtime'] = 'N/A'
144
+ info['gpu_count'] = 0
145
+ info['gpu_model'] = 'N/A'
146
+ info['gpu_memory_gb'] = 'N/A'
147
+
148
+ # Check for nvcc (CUDA compiler)
149
+ nvcc_path = shutil.which('nvcc')
150
+ info['nvcc'] = 'found' if nvcc_path else 'not found'
151
+
152
+ if nvcc_path:
153
+ try:
154
+ result = subprocess.run(['nvcc', '--version'],
155
+ capture_output=True, text=True, check=True)
156
+ # Extract version from output like "Cuda compilation tools, release 11.8, V11.8.89"
157
+ version_line = result.stdout.split('\n')[0]
158
+ if 'release' in version_line:
159
+ version = version_line.split('release')[1].split(',')[0].strip()
160
+ info['nvcc_version'] = version
161
+ else:
162
+ info['nvcc_version'] = 'unknown'
163
+ except subprocess.CalledProcessError:
164
+ info['nvcc_version'] = 'unknown'
165
+ else:
166
+ info['nvcc_version'] = 'N/A'
167
+
168
+ # Check CUDA installation paths
169
+ cuda_paths = [
170
+ '/usr/local/cuda',
171
+ '/opt/cuda',
172
+ '/usr/cuda',
173
+ os.path.expanduser('~/cuda')
174
+ ]
175
+
176
+ cuda_installed = False
177
+ for path in cuda_paths:
178
+ if os.path.exists(path):
179
+ cuda_installed = True
180
+ break
181
+
182
+ info['cuda_installation'] = 'present' if cuda_installed else 'not present'
183
+
184
+ # Check if CUDA is on PATH
185
+ cuda_on_path = any('cuda' in p.lower() for p in os.environ.get('PATH', '').split(os.pathsep))
186
+ info['cuda_on_path'] = 'yes' if cuda_on_path else 'no'
187
+
188
+ return info
189
+
190
+
191
+ def run_doctor():
192
+ """Run the doctor command to diagnose system issues."""
193
+ print("🔍 RapidFire AI System Diagnostics")
194
+ print("=" * 50)
195
+
196
+ # Python Information
197
+ print("\n🐍 Python Environment:")
198
+ print("-" * 30)
199
+ python_info = get_python_info()
200
+ print(f"Version: {python_info['version'].split()[0]}")
201
+ print(f"Implementation: {python_info['implementation']}")
202
+ print(f"Executable: {python_info['executable']}")
203
+ print(f"Conda Environment: {python_info['conda_env']}")
204
+ print(f"Virtual Environment: {python_info['venv']}")
205
+
206
+ # Pip Packages
207
+ print("\n📦 Installed Packages:")
208
+ print("-" * 30)
209
+ pip_output = get_pip_packages()
210
+ if pip_output != "Failed to get pip packages":
211
+ # Show only relevant packages
212
+ relevant_packages = ['rapidfireai', 'mlflow', 'torch', 'transformers', 'flask', 'gunicorn', 'peft', 'trl', 'bitsandbytes', 'nltk', 'evaluate', 'rouge-score', 'sentencepiece']
213
+ lines = pip_output.split('\n')
214
+ for line in lines:
215
+ if any(pkg.lower() in line.lower() for pkg in relevant_packages):
216
+ print(line)
217
+ print("... (showing only relevant packages)")
218
+ else:
219
+ print(pip_output)
220
+
221
+ # GPU Information
222
+ print("\n🚀 GPU & CUDA Information:")
223
+ print("-" * 30)
224
+ gpu_info = get_gpu_info()
225
+ print(f"nvidia-smi: {gpu_info['nvidia_smi']}")
226
+
227
+ if gpu_info['nvidia_smi'] == 'found':
228
+ print(f"Driver Version: {gpu_info['driver_version']}")
229
+ print(f"CUDA Runtime: {gpu_info['cuda_runtime']}")
230
+ print(f"GPU Count: {gpu_info['gpu_count']}")
231
+
232
+ if gpu_info['gpu_count'] > 0:
233
+ if 'gpu_details' in gpu_info:
234
+ print("GPU Details:")
235
+ for i, gpu in enumerate(gpu_info['gpu_details']):
236
+ print(f" GPU {i}: {gpu['name']} ({gpu['memory_gb']} GB)")
237
+ else:
238
+ print(f"GPU Model: {gpu_info['gpu_model']}")
239
+ print(f"Total VRAM: {gpu_info['gpu_memory_gb']} GB")
240
+
241
+ print(f"nvcc: {gpu_info['nvcc']}")
242
+ if gpu_info['nvcc'] == 'found':
243
+ print(f"nvcc Version: {gpu_info['nvcc_version']}")
244
+
245
+ print(f"CUDA Installation: {gpu_info['cuda_installation']}")
246
+ print(f"CUDA on PATH: {gpu_info['cuda_on_path']}")
247
+
248
+ # System Information
249
+ print("\n💻 System Information:")
250
+ print("-" * 30)
251
+ print(f"Platform: {platform.platform()}")
252
+ print(f"Architecture: {platform.machine()}")
253
+ print(f"Processor: {platform.processor()}")
254
+
255
+ # Environment Variables
256
+ print("\n🔧 Environment Variables:")
257
+ print("-" * 30)
258
+ relevant_vars = ['CUDA_HOME', 'CUDA_PATH', 'LD_LIBRARY_PATH', 'PATH']
259
+ for var in relevant_vars:
260
+ value = os.environ.get(var, 'not set')
261
+ if value != 'not set' and len(value) > 100:
262
+ value = value[:100] + "..."
263
+ print(f"{var}: {value}")
264
+
265
+ print("\n✅ Diagnostics complete!")
266
+ return 0
267
+
268
+ def get_cuda_version():
269
+ """Detect CUDA version from nvcc or nvidia-smi"""
270
+ try:
271
+ result = subprocess.run(['nvcc', '--version'],
272
+ capture_output=True, text=True, check=True)
273
+ match = re.search(r'release (\d+)\.(\d+)', result.stdout)
274
+ if match:
275
+ return int(match.group(1))
276
+ except (subprocess.CalledProcessError, FileNotFoundError):
277
+ try:
278
+ result = subprocess.run(['nvidia-smi'],
279
+ capture_output=True, text=True, check=True)
280
+ match = re.search(r'CUDA Version: (\d+)\.(\d+)', result.stdout)
281
+ if match:
282
+ return int(match.group(1))
283
+ except (subprocess.CalledProcessError, FileNotFoundError):
284
+ pass
285
+ return None
286
+
287
+ def get_compute_capability():
288
+ """Get compute capability from nvidia-smi"""
289
+ try:
290
+ result = subprocess.run(['nvidia-smi', '--query-gpu=compute_cap', '--format=csv,noheader,nounits'],
291
+ capture_output=True, text=True, check=True)
292
+ match = re.search(r'(\d+)\.(\d+)', result.stdout)
293
+ if match:
294
+ return int(match.group(1))
295
+ except (subprocess.CalledProcessError, FileNotFoundError):
296
+ return None
297
+
298
+ def install_packages():
299
+ """Install packages for the RapidFire AI project."""
300
+ packages = []
301
+ # Generate CUDA requirements file
302
+ cuda_major = get_cuda_version()
303
+ compute_capability = get_compute_capability()
304
+ print(f"CUDA major version: {cuda_major}")
305
+ print(f"Compute capability: {compute_capability}")
306
+ if cuda_major == 12:
307
+ print(f"\n🎯 Detected CUDA {cuda_major}.x")
308
+ packages.append({"package": "vllm==0.10.1.1", "extra_args": ["--torch-backend=cu126"]})
309
+ elif cuda_major == 11:
310
+ print(f"\n🎯 Detected CUDA {cuda_major}.x")
311
+ packages.append({"package": "vllm==0.10.1.1", "extra_args": ["--torch-backend=cu118"]})
312
+ else:
313
+ print("\n⚠️ CUDA version not detected or unsupported.")
314
+ if compute_capability == 7:
315
+ print(f"\n🎯 Detected CUDA Compute Capability {compute_capability}.x")
316
+ packages.append({"package": "flash-attn==1.0.9", "extra_args": ["--no-build-isolation"]})
317
+ elif compute_capability == 8:
318
+ print(f"\n🎯 Detected CUDA Compute Capability {compute_capability}.x")
319
+ packages.append({"package": "flash-attn==2.8.3", "extra_args": ["--no-build-isolation"]})
320
+ else:
321
+ print("\n⚠️ CUDA Compute Capability not detected or unsupported.")
322
+
323
+ for package_info in packages:
324
+ try:
325
+ package = package_info["package"]
326
+ cmd = [sys.executable, "-m", "uv", "pip", "install", package] + package_info["extra_args"]
327
+ print(f" Installing {package}...")
328
+ subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
329
+ print(f"✅ Successfully installed {package}")
330
+ except subprocess.CalledProcessError as e:
331
+ print(f"❌ Failed to install {package}")
332
+ print(f" Error: {e}")
333
+ print(f" You may need to install {package} manually")
334
+ return 0
335
+
336
+ def run_init():
337
+ """Run the init command to initialize the project."""
338
+ print("🔧 Initializing RapidFire AI project...")
339
+ print("-" * 30)
340
+ print("Initializing project...")
341
+ install_packages()
342
+ return 0
343
+
344
+ def main():
345
+ """Main entry point for the rapidfire-start command."""
346
+ parser = argparse.ArgumentParser(
347
+ description="RapidFire AI - Start/stop/manage services",
348
+ prog="rapidfire"
349
+ )
350
+
351
+ parser.add_argument(
352
+ "command",
353
+ nargs="?",
354
+ default="start",
355
+ choices=["start", "stop", "status", "restart", "setup", "doctor", "init"],
356
+ help="Command to execute (default: start)"
357
+ )
358
+
359
+ parser.add_argument(
360
+ "--version",
361
+ action="version",
362
+ version=f"RapidFire AI {__version__}"
363
+ )
364
+
365
+ args = parser.parse_args()
366
+
367
+ # Handle doctor command separately
368
+ if args.command == "doctor":
369
+ return run_doctor()
370
+
371
+ # Handle init command separately
372
+ if args.command == "init":
373
+ return run_init()
374
+
375
+ # Run the script with the specified command
376
+ return run_script([args.command])
377
+
378
+
379
+ if __name__ == "__main__":
380
+ sys.exit(main())
File without changes
@@ -0,0 +1,135 @@
1
+ """Interface for the database."""
2
+
3
+ import functools
4
+ import os
5
+ import sqlite3
6
+ import time
7
+ from typing import Any, Callable
8
+
9
+ from rapidfireai.utils.constants import DBConfig
10
+ from rapidfireai.utils.exceptions import DBException
11
+
12
+
13
+ class DatabaseInterface:
14
+ """Interface for the database."""
15
+
16
+ def __init__(self):
17
+ try:
18
+ if not os.path.exists(DBConfig.DB_PATH):
19
+ path = os.path.dirname(DBConfig.DB_PATH)
20
+ os.makedirs(path, exist_ok=True)
21
+ print(f"Created directory for database at {path}")
22
+
23
+ self.conn: sqlite3.Connection = sqlite3.connect(
24
+ DBConfig.DB_PATH,
25
+ timeout=DBConfig.CONNECTION_TIMEOUT,
26
+ check_same_thread=False,
27
+ isolation_level=None,
28
+ )
29
+
30
+ # Configure database with all PRAGMA settings
31
+ pragma_sql = f"""
32
+ PRAGMA cache_size={DBConfig.CACHE_SIZE};
33
+ PRAGMA mmap_size={DBConfig.MMAP_SIZE};
34
+ PRAGMA page_size={DBConfig.PAGE_SIZE};
35
+ PRAGMA busy_timeout={DBConfig.BUSY_TIMEOUT};
36
+ PRAGMA journal_mode=WAL;
37
+ PRAGMA synchronous=NORMAL;
38
+ PRAGMA temp_store=MEMORY;
39
+ PRAGMA foreign_keys=ON;
40
+ """
41
+ _ = self.conn.executescript(pragma_sql)
42
+
43
+ self.cursor: sqlite3.Cursor = self.conn.cursor()
44
+
45
+ except sqlite3.Error as e:
46
+ raise DBException(f"Failed to initialize database connection: {e}") from e
47
+ except Exception as e:
48
+ raise DBException(f"Unexpected error during database initialization: {e}") from e
49
+
50
+ @staticmethod
51
+ def retry_on_locked(
52
+ max_retries: int = DBConfig.DEFAULT_MAX_RETRIES,
53
+ base_delay: float = DBConfig.DEFAULT_BASE_DELAY,
54
+ max_delay: float = DBConfig.DEFAULT_MAX_DELAY,
55
+ ) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
56
+ """Decorator to retry operations when database is locked"""
57
+
58
+ def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
59
+ @functools.wraps(func)
60
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
61
+ last_exception = None
62
+ for attempt in range(max_retries):
63
+ try:
64
+ return func(*args, **kwargs)
65
+ except sqlite3.OperationalError as e:
66
+ if "database is locked" in str(e).lower():
67
+ last_exception = e
68
+ if attempt < max_retries - 1:
69
+ # Exponential backoff with jitter
70
+ delay = min(base_delay * (2**attempt), max_delay)
71
+ delay += time.time() % 0.1 # Add small jitter
72
+ time.sleep(delay)
73
+ continue
74
+ # Re-raise if it's not a "database is locked" error
75
+ raise
76
+ # If we get here, all retries failed
77
+ if last_exception:
78
+ raise last_exception
79
+ else:
80
+ raise RuntimeError("All retries failed but no exception was captured")
81
+
82
+ return wrapper
83
+
84
+ return decorator
85
+
86
+ def close(self) -> None:
87
+ """Close the database connection properly"""
88
+ try:
89
+ if self.conn:
90
+ self.conn.close()
91
+ except sqlite3.Error as e:
92
+ raise DBException(f"Error closing database connection: {e}") from e
93
+ except Exception as e:
94
+ raise DBException(f"Unexpected error closing database connection: {e}") from e
95
+
96
+ def optimize_periodically(self) -> None:
97
+ """Run periodic optimization - call this occasionally, not on every query"""
98
+ try:
99
+ _ = self.conn.execute("PRAGMA optimize")
100
+ except sqlite3.Error as e:
101
+ raise DBException(f"Failed to optimize database: {e}") from e
102
+ except Exception as e:
103
+ raise DBException(f"Unexpected error during database optimization: {e}") from e
104
+
105
+ def execute(
106
+ self,
107
+ query: str,
108
+ params: dict[str, Any] | tuple[Any, ...] | None = None,
109
+ fetch: bool = False,
110
+ commit: bool = False,
111
+ ) -> list[Any] | tuple[Any] | None:
112
+ """Execute a query with automatic retry on database locked errors"""
113
+ # Validate that either fetch or commit is True
114
+ if not fetch and not commit:
115
+ raise ValueError("Either fetch or commit must be True")
116
+
117
+ try:
118
+ # Execute the query with parameters if provided
119
+ if params:
120
+ result = self.cursor.execute(query, params)
121
+ else:
122
+ result = self.cursor.execute(query)
123
+
124
+ # Commit the transaction if commit is True
125
+ if commit:
126
+ self.conn.commit()
127
+
128
+ # Return the result if fetch is True
129
+ if fetch:
130
+ return result.fetchall()
131
+
132
+ except sqlite3.Error as e:
133
+ raise DBException(f"Database error executing query '{query[:50]}...': {e}") from e
134
+ except Exception as e:
135
+ raise DBException(f"Unexpected error executing query '{query[:50]}...': {e}") from e