kaia-brainbox 0.0.0__tar.gz

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.
Files changed (263) hide show
  1. kaia_brainbox-0.0.0/PKG-INFO +637 -0
  2. kaia_brainbox-0.0.0/README.md +609 -0
  3. kaia_brainbox-0.0.0/brainbox/deciders/__init__.py +6 -0
  4. kaia_brainbox-0.0.0/brainbox/deciders/common/__init__.py +18 -0
  5. kaia_brainbox-0.0.0/brainbox/deciders/images/__init__.py +3 -0
  6. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/__init__.py +1 -0
  7. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/api.py +89 -0
  8. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/container/main.py +44 -0
  9. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/controller.py +166 -0
  10. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/model.py +0 -0
  11. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/run.py +12 -0
  12. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/settings.py +75 -0
  13. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/tests.py +69 -0
  14. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/workflows/__init__.py +5 -0
  15. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/workflows/template.py +133 -0
  16. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/workflows/text_to_image.py +31 -0
  17. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/workflows/upscale.py +18 -0
  18. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/workflows/wd14_interrogate.py +27 -0
  19. kaia_brainbox-0.0.0/brainbox/deciders/images/comfyui/workflows/workflow.py +15 -0
  20. kaia_brainbox-0.0.0/brainbox/deciders/images/video_to_images/__init__.py +1 -0
  21. kaia_brainbox-0.0.0/brainbox/deciders/images/video_to_images/api.py +38 -0
  22. kaia_brainbox-0.0.0/brainbox/deciders/images/video_to_images/container/__init__.py +0 -0
  23. kaia_brainbox-0.0.0/brainbox/deciders/images/video_to_images/container/main.py +18 -0
  24. kaia_brainbox-0.0.0/brainbox/deciders/images/video_to_images/container/model.py +5 -0
  25. kaia_brainbox-0.0.0/brainbox/deciders/images/video_to_images/container/server.py +102 -0
  26. kaia_brainbox-0.0.0/brainbox/deciders/images/video_to_images/controller.py +133 -0
  27. kaia_brainbox-0.0.0/brainbox/deciders/images/video_to_images/run.py +10 -0
  28. kaia_brainbox-0.0.0/brainbox/deciders/images/video_to_images/settings.py +5 -0
  29. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/__init__.py +1 -0
  30. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/api.py +49 -0
  31. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/container/__init__.py +0 -0
  32. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/container/main.py +7 -0
  33. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/container/server.py +121 -0
  34. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/container/validation_objects.py +11 -0
  35. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/controller.py +143 -0
  36. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/model.py +29 -0
  37. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/run.py +7 -0
  38. kaia_brainbox-0.0.0/brainbox/deciders/images/yolo/settings.py +11 -0
  39. kaia_brainbox-0.0.0/brainbox/deciders/plugins/__init__.py +0 -0
  40. kaia_brainbox-0.0.0/brainbox/deciders/text/__init__.py +1 -0
  41. kaia_brainbox-0.0.0/brainbox/deciders/text/ollama/__init__.py +1 -0
  42. kaia_brainbox-0.0.0/brainbox/deciders/text/ollama/api.py +50 -0
  43. kaia_brainbox-0.0.0/brainbox/deciders/text/ollama/controller.py +70 -0
  44. kaia_brainbox-0.0.0/brainbox/deciders/text/ollama/model.py +27 -0
  45. kaia_brainbox-0.0.0/brainbox/deciders/text/ollama/run.py +15 -0
  46. kaia_brainbox-0.0.0/brainbox/deciders/text/ollama/settings.py +10 -0
  47. kaia_brainbox-0.0.0/brainbox/deciders/utils/__init__.py +4 -0
  48. kaia_brainbox-0.0.0/brainbox/deciders/utils/boilerplate/__init__.py +1 -0
  49. kaia_brainbox-0.0.0/brainbox/deciders/utils/boilerplate/api.py +47 -0
  50. kaia_brainbox-0.0.0/brainbox/deciders/utils/boilerplate/container/__init__.py +0 -0
  51. kaia_brainbox-0.0.0/brainbox/deciders/utils/boilerplate/container/main.py +20 -0
  52. kaia_brainbox-0.0.0/brainbox/deciders/utils/boilerplate/container/server.py +51 -0
  53. kaia_brainbox-0.0.0/brainbox/deciders/utils/boilerplate/controller.py +178 -0
  54. kaia_brainbox-0.0.0/brainbox/deciders/utils/boilerplate/model.py +20 -0
  55. kaia_brainbox-0.0.0/brainbox/deciders/utils/boilerplate/run.py +8 -0
  56. kaia_brainbox-0.0.0/brainbox/deciders/utils/boilerplate/settings.py +9 -0
  57. kaia_brainbox-0.0.0/brainbox/deciders/utils/collector/__init__.py +1 -0
  58. kaia_brainbox-0.0.0/brainbox/deciders/utils/collector/collector.py +40 -0
  59. kaia_brainbox-0.0.0/brainbox/deciders/utils/collector/collector_to_media_library_convertor.py +67 -0
  60. kaia_brainbox-0.0.0/brainbox/deciders/utils/collector/functional_task_builder.py +19 -0
  61. kaia_brainbox-0.0.0/brainbox/deciders/utils/collector/task_builder.py +61 -0
  62. kaia_brainbox-0.0.0/brainbox/deciders/utils/fake_file.py +19 -0
  63. kaia_brainbox-0.0.0/brainbox/deciders/utils/fake_text.py +9 -0
  64. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/__init__.py +3 -0
  65. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/__init__.py +1 -0
  66. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/api.py +69 -0
  67. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/container/__init__.py +0 -0
  68. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/container/classifier.py +81 -0
  69. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/container/main.py +19 -0
  70. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/container/server.py +75 -0
  71. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/controller.py +236 -0
  72. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/produce_test_media_library.py +29 -0
  73. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/run.py +9 -0
  74. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/resemblyzer/settings.py +6 -0
  75. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/__init__.py +1 -0
  76. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/api.py +54 -0
  77. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/container/__init__.py +0 -0
  78. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/container/main.py +25 -0
  79. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/container/model.py +33 -0
  80. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/container/server.py +63 -0
  81. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/container/train.py +140 -0
  82. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/container/transcribe.py +52 -0
  83. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/container/utils.py +23 -0
  84. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/controller.py +67 -0
  85. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/model.py +38 -0
  86. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/run.py +7 -0
  87. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/settings.py +11 -0
  88. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/rhasspy_kaldi/tests.py +90 -0
  89. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/whisper/__init__.py +1 -0
  90. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/whisper/api.py +72 -0
  91. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/whisper/container/__init__.py +0 -0
  92. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/whisper/container/main.py +21 -0
  93. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/whisper/container/server.py +67 -0
  94. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/whisper/controller.py +201 -0
  95. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/whisper/model.py +25 -0
  96. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/whisper/run.py +6 -0
  97. kaia_brainbox-0.0.0/brainbox/deciders/voice_analysis/whisper/settings.py +14 -0
  98. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/__init__.py +3 -0
  99. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/__init__.py +1 -0
  100. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/api.py +90 -0
  101. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/container/__init__.py +0 -0
  102. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/container/installer_script.py +5 -0
  103. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/container/main.py +49 -0
  104. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/container/server.py +125 -0
  105. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/container/tts_loader.py +38 -0
  106. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/controller.py +322 -0
  107. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/run.py +11 -0
  108. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/settings.py +28 -0
  109. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/coqui_tts/tests.py +71 -0
  110. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/open_tts/__init__.py +1 -0
  111. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/open_tts/api.py +36 -0
  112. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/open_tts/controller.py +45 -0
  113. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/open_tts/run.py +7 -0
  114. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/open_tts/settings.py +6 -0
  115. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/tortoise_tts/__init__.py +1 -0
  116. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/tortoise_tts/api.py +56 -0
  117. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/tortoise_tts/container/__init__.py +0 -0
  118. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/tortoise_tts/container/generate.py +59 -0
  119. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/tortoise_tts/container/main.py +64 -0
  120. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/tortoise_tts/controller.py +246 -0
  121. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/tortoise_tts/run.py +6 -0
  122. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/tortoise_tts/settings.py +9 -0
  123. kaia_brainbox-0.0.0/brainbox/deciders/voice_generation/tortoise_tts/upload_prerequisite.py +16 -0
  124. kaia_brainbox-0.0.0/brainbox/framework/__init__.py +6 -0
  125. kaia_brainbox-0.0.0/brainbox/framework/brainbox/__init__.py +9 -0
  126. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/__init__.py +4 -0
  127. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/api.py +123 -0
  128. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/html_helpers/__init__.py +3 -0
  129. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/html_helpers/batch_page.py +120 -0
  130. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/html_helpers/main_page.py +122 -0
  131. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/html_helpers/operator_log_page.py +16 -0
  132. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/interface.py +123 -0
  133. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/server.py +61 -0
  134. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/serverless_test.py +37 -0
  135. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/service.py +138 -0
  136. kaia_brainbox-0.0.0/brainbox/framework/brainbox/app/task.py +30 -0
  137. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/__init__.py +7 -0
  138. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/combined_task.py +31 -0
  139. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/command.py +18 -0
  140. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/extended_task.py +34 -0
  141. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/helper_methods.py +80 -0
  142. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/one_brainbox_task_factory.py +20 -0
  143. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/postprocessors.py +52 -0
  144. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/prerequisites.py +44 -0
  145. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/task.py +83 -0
  146. kaia_brainbox-0.0.0/brainbox/framework/brainbox/task/task_builder.py +99 -0
  147. kaia_brainbox-0.0.0/brainbox/framework/common/__init__.py +9 -0
  148. kaia_brainbox-0.0.0/brainbox/framework/common/api_utils.py +34 -0
  149. kaia_brainbox-0.0.0/brainbox/framework/common/decider.py +62 -0
  150. kaia_brainbox-0.0.0/brainbox/framework/common/file.py +99 -0
  151. kaia_brainbox-0.0.0/brainbox/framework/common/file_io.py +63 -0
  152. kaia_brainbox-0.0.0/brainbox/framework/common/file_like.py +68 -0
  153. kaia_brainbox-0.0.0/brainbox/framework/common/fork.py +56 -0
  154. kaia_brainbox-0.0.0/brainbox/framework/common/fork_worker.py +26 -0
  155. kaia_brainbox-0.0.0/brainbox/framework/common/loc.py +105 -0
  156. kaia_brainbox-0.0.0/brainbox/framework/common/logger.py +8 -0
  157. kaia_brainbox-0.0.0/brainbox/framework/common/marshalling/__init__.py +4 -0
  158. kaia_brainbox-0.0.0/brainbox/framework/common/marshalling/api.py +44 -0
  159. kaia_brainbox-0.0.0/brainbox/framework/common/marshalling/api_binding.py +35 -0
  160. kaia_brainbox-0.0.0/brainbox/framework/common/marshalling/endpoint.py +24 -0
  161. kaia_brainbox-0.0.0/brainbox/framework/common/marshalling/format.py +56 -0
  162. kaia_brainbox-0.0.0/brainbox/framework/common/marshalling/marshalling_metadata.py +38 -0
  163. kaia_brainbox-0.0.0/brainbox/framework/common/marshalling/server.py +43 -0
  164. kaia_brainbox-0.0.0/brainbox/framework/common/marshalling/server_binding.py +49 -0
  165. kaia_brainbox-0.0.0/brainbox/framework/common/marshalling/test_api.py +27 -0
  166. kaia_brainbox-0.0.0/brainbox/framework/common/signature_processor.py +57 -0
  167. kaia_brainbox-0.0.0/brainbox/framework/controllers/__init__.py +2 -0
  168. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/__init__.py +5 -0
  169. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/api.py +58 -0
  170. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/dto.py +47 -0
  171. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/html_helpers/__init__.py +2 -0
  172. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/html_helpers/installation_report_page.py +28 -0
  173. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/html_helpers/page.py +71 -0
  174. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/html_helpers/status_page.py +79 -0
  175. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/interface.py +57 -0
  176. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/logging.py +67 -0
  177. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/server.py +100 -0
  178. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/service.py +215 -0
  179. kaia_brainbox-0.0.0/brainbox/framework/controllers/app/setuper.py +64 -0
  180. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/__init__.py +17 -0
  181. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/connection_settings.py +6 -0
  182. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/controller.py +156 -0
  183. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/controller_context.py +49 -0
  184. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/controller_over_decider.py +58 -0
  185. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/controller_registry.py +130 -0
  186. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/docker_controller.py +144 -0
  187. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/docker_web_service_api.py +41 -0
  188. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/docker_web_service_controller.py +66 -0
  189. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/model_downloading_controller.py +80 -0
  190. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/notebookable_controller.py +7 -0
  191. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/on_demand_docker_api.py +14 -0
  192. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/on_demand_docker_controller.py +19 -0
  193. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/resource_folder.py +14 -0
  194. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/run_configuration.py +88 -0
  195. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/runner.py +18 -0
  196. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/single_loadable_model_api.py +10 -0
  197. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/test_report/__init__.py +2 -0
  198. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/test_report/main_section_content.py +5 -0
  199. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/test_report/self_test_report_page.py +115 -0
  200. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/test_report/test_report.py +58 -0
  201. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/test_report/test_report_item.py +55 -0
  202. kaia_brainbox-0.0.0/brainbox/framework/controllers/controller/test_report/test_report_section.py +10 -0
  203. kaia_brainbox-0.0.0/brainbox/framework/deployment/__init__.py +5 -0
  204. kaia_brainbox-0.0.0/brainbox/framework/deployment/container_runner/__init__.py +1 -0
  205. kaia_brainbox-0.0.0/brainbox/framework/deployment/container_runner/container_runner.py +58 -0
  206. kaia_brainbox-0.0.0/brainbox/framework/deployment/deployment.py +69 -0
  207. kaia_brainbox-0.0.0/brainbox/framework/deployment/executor/__init__.py +8 -0
  208. kaia_brainbox-0.0.0/brainbox/framework/deployment/executor/command.py +15 -0
  209. kaia_brainbox-0.0.0/brainbox/framework/deployment/executor/executor.py +32 -0
  210. kaia_brainbox-0.0.0/brainbox/framework/deployment/executor/file_system.py +27 -0
  211. kaia_brainbox-0.0.0/brainbox/framework/deployment/executor/local_executor.py +53 -0
  212. kaia_brainbox-0.0.0/brainbox/framework/deployment/executor/local_file_system.py +28 -0
  213. kaia_brainbox-0.0.0/brainbox/framework/deployment/executor/machine.py +14 -0
  214. kaia_brainbox-0.0.0/brainbox/framework/deployment/executor/ssh_executor.py +41 -0
  215. kaia_brainbox-0.0.0/brainbox/framework/deployment/executor/ssh_file_system.py +47 -0
  216. kaia_brainbox-0.0.0/brainbox/framework/deployment/image_builder/__init__.py +2 -0
  217. kaia_brainbox-0.0.0/brainbox/framework/deployment/image_builder/image_builder.py +9 -0
  218. kaia_brainbox-0.0.0/brainbox/framework/deployment/image_builder/small_image_builder.py +120 -0
  219. kaia_brainbox-0.0.0/brainbox/framework/deployment/image_source/__init__.py +5 -0
  220. kaia_brainbox-0.0.0/brainbox/framework/deployment/image_source/docker_io_image_source.py +41 -0
  221. kaia_brainbox-0.0.0/brainbox/framework/deployment/image_source/hacked_docker_io_image_source.py +16 -0
  222. kaia_brainbox-0.0.0/brainbox/framework/deployment/image_source/image_source.py +38 -0
  223. kaia_brainbox-0.0.0/brainbox/framework/deployment/image_source/local_image_source.py +25 -0
  224. kaia_brainbox-0.0.0/brainbox/framework/deployment/image_source/remote_public_image_source.py +22 -0
  225. kaia_brainbox-0.0.0/brainbox/framework/job_processing/__init__.py +4 -0
  226. kaia_brainbox-0.0.0/brainbox/framework/job_processing/core/__init__.py +8 -0
  227. kaia_brainbox-0.0.0/brainbox/framework/job_processing/core/core.py +47 -0
  228. kaia_brainbox-0.0.0/brainbox/framework/job_processing/core/decider_instance_key.py +10 -0
  229. kaia_brainbox-0.0.0/brainbox/framework/job_processing/core/job.py +61 -0
  230. kaia_brainbox-0.0.0/brainbox/framework/job_processing/core/job_for_planner.py +15 -0
  231. kaia_brainbox-0.0.0/brainbox/framework/job_processing/core/operator_log.py +78 -0
  232. kaia_brainbox-0.0.0/brainbox/framework/job_processing/core/operator_message.py +21 -0
  233. kaia_brainbox-0.0.0/brainbox/framework/job_processing/core/operator_state.py +37 -0
  234. kaia_brainbox-0.0.0/brainbox/framework/job_processing/core/trackable_session_factory.py +33 -0
  235. kaia_brainbox-0.0.0/brainbox/framework/job_processing/main_loop/__init__.py +6 -0
  236. kaia_brainbox-0.0.0/brainbox/framework/job_processing/main_loop/cancel_action.py +22 -0
  237. kaia_brainbox-0.0.0/brainbox/framework/job_processing/main_loop/check_ready_action.py +59 -0
  238. kaia_brainbox-0.0.0/brainbox/framework/job_processing/main_loop/main_loop.py +78 -0
  239. kaia_brainbox-0.0.0/brainbox/framework/job_processing/main_loop/remove_incorrect_action.py +13 -0
  240. kaia_brainbox-0.0.0/brainbox/framework/job_processing/main_loop/task_status_updater.py +52 -0
  241. kaia_brainbox-0.0.0/brainbox/framework/job_processing/main_loop/tasks_for_planner_sync.py +56 -0
  242. kaia_brainbox-0.0.0/brainbox/framework/job_processing/operator/__init__.py +1 -0
  243. kaia_brainbox-0.0.0/brainbox/framework/job_processing/operator/decider_log.py +14 -0
  244. kaia_brainbox-0.0.0/brainbox/framework/job_processing/operator/file_postprocessor.py +24 -0
  245. kaia_brainbox-0.0.0/brainbox/framework/job_processing/operator/operator.py +75 -0
  246. kaia_brainbox-0.0.0/brainbox/framework/job_processing/planner/__init__.py +5 -0
  247. kaia_brainbox-0.0.0/brainbox/framework/job_processing/planner/assign_action.py +55 -0
  248. kaia_brainbox-0.0.0/brainbox/framework/job_processing/planner/planner.py +20 -0
  249. kaia_brainbox-0.0.0/brainbox/framework/job_processing/planner/planner_action.py +4 -0
  250. kaia_brainbox-0.0.0/brainbox/framework/job_processing/planner/start_action.py +85 -0
  251. kaia_brainbox-0.0.0/brainbox/framework/job_processing/planner/stop_action.py +16 -0
  252. kaia_brainbox-0.0.0/brainbox/framework/job_processing/planner_implementation/__init__.py +2 -0
  253. kaia_brainbox-0.0.0/brainbox/framework/job_processing/planner_implementation/always_on_planner.py +24 -0
  254. kaia_brainbox-0.0.0/brainbox/framework/job_processing/planner_implementation/simple_planner.py +97 -0
  255. kaia_brainbox-0.0.0/brainbox/framework/media_library/__init__.py +1 -0
  256. kaia_brainbox-0.0.0/brainbox/framework/media_library/media_library.py +244 -0
  257. kaia_brainbox-0.0.0/kaia_brainbox.egg-info/PKG-INFO +637 -0
  258. kaia_brainbox-0.0.0/kaia_brainbox.egg-info/SOURCES.txt +261 -0
  259. kaia_brainbox-0.0.0/kaia_brainbox.egg-info/dependency_links.txt +1 -0
  260. kaia_brainbox-0.0.0/kaia_brainbox.egg-info/requires.txt +9 -0
  261. kaia_brainbox-0.0.0/kaia_brainbox.egg-info/top_level.txt +2 -0
  262. kaia_brainbox-0.0.0/pyproject.toml +49 -0
  263. kaia_brainbox-0.0.0/setup.cfg +4 -0
@@ -0,0 +1,637 @@
1
+ Metadata-Version: 2.1
2
+ Name: kaia-brainbox
3
+ Version: 0.0.0
4
+ Summary: Web-server and API to access the curated set of AI-deciders, packaged as containers
5
+ Author-email: Yuri Okulovsky <yuri.okulovsky@gmail.com>
6
+ License: GPLv3
7
+ Project-URL: repository, https://github.com/okulovsky/kaia/tree/main/brainbox
8
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Intended Audience :: Information Technology
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Classifier: Development Status :: 4 - Beta
18
+ Requires-Python: <4.0,>=3.10
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: yo_fluq_ds
21
+ Requires-Dist: flask
22
+ Requires-Dist: requests
23
+ Requires-Dist: sqlalchemy
24
+ Provides-Extra: dev
25
+ Requires-Dist: tox; extra == "dev"
26
+ Requires-Dist: tox-conda; extra == "dev"
27
+ Requires-Dist: twine; extra == "dev"
28
+
29
+ # Introduction
30
+
31
+ BrainBox provides easy HTTP access to a set of curated Docker containers
32
+ with AI-systems processing images, texts and sounds.
33
+ It comes with API endpoints to build the container and download basic models,
34
+ self-tests and documentation, as well as unified access to all the models.
35
+ The main use case is fast prototyping of small AI-driven products:
36
+ managing chats in messengers, self-hosted voice assistants,
37
+ media processing (translation, covering images), etc.
38
+ BrainBox is open-source and self-hosted, so no external APIs are needed;
39
+ GPU is recommended for some, but not all, models.
40
+
41
+ BrainBox is not a production-ready solution. **Do not use it** in production environment,
42
+ since it doesn't have any security features, isn't really compatible with high and even
43
+ moderate load, and at the same time may have a big impact on the system's resources.
44
+ The suggested use of BrainBox is your own home machine,
45
+ where the security is provided on the network, not application, level.
46
+ Ideally, this machine would have a decent GPU unit: many AI-systems do not require GPU,
47
+ but some (the most interesting ones, of course) are practically useless without it,
48
+ and few won't even run.
49
+
50
+ ## Included deciders
51
+
52
+ They are many.
53
+ At some point, BrainBox will have a comprehensive documentation for each of them, but we're not there yet.
54
+ Important deciders are:
55
+ * For TTS, text-to-speech:
56
+ * [OpenTTS](https://github.com/synesthesiam/opentts) provides a decent baseline for english language with VITS model
57
+ * [CoquiTTS](https://github.com/coqui-ai/TTS) is a framework supporting many different models.
58
+ That includes VITS as well as YourTTS, and, of course, their own XTTS, that can do a good voice cloning.
59
+ * [TortoiseTTS](https://github.com/neonbjb/tortoise-tts) is, in my opinion, still the best in terms of quality.
60
+ It is very slow, but not as slow as it used to be.
61
+ * For STT, speech-to-text, and other voice analysis:
62
+ * [Whisper](https://github.com/WhisperSpeech/WhisperSpeech) is a de-facto standard.
63
+ * [Kaldi](https://kaldi-asr.org/), which we use via its implementation in [Rhasspy](https://rhasspy.readthedocs.io/en/latest/),
64
+ provides much faster and accurate result _over the closed grammar and vocabulary_.
65
+ It is not really a general solution for STT, but is perfect for home assistants.
66
+ * [Resemblyzer](https://github.com/resemble-ai/Resemblyzer) does speaker identification.
67
+ * For text processing:
68
+ * [Ollama](https://ollama.com/), a de-facto standard for LLM management, is supported.
69
+ * For image generation and processing:
70
+ * [ComfyUI](https://github.com/comfyanonymous/ComfyUI), a standard for image generation, is supported
71
+ * [YOLO](https://docs.ultralytics.com/) is supported for object detection.
72
+
73
+ ... And more are coming.
74
+ Once you install BrainBox, you will have all these AIs privately and free of charge on your machine,
75
+ accessible via user-friendly Python API, or by simple HTTP requests!
76
+
77
+ # Installation
78
+
79
+ ## Docker
80
+
81
+ You need [Docker](https://docs.docker.com/engine/install/) installed in your system,
82
+ and the access granted to the current user to run `docker` from command line without elevated privileges.
83
+ The command
84
+
85
+ ```commandline
86
+ docker run hello-world
87
+ ```
88
+
89
+ should work successfully and produce the text starting with "Hello from Docker!"
90
+
91
+ ## Python environment
92
+
93
+ [Anaconda](https://www.anaconda.com/download/success) is recommended to manage Python's
94
+ environments. Create an environment for e.g. Python 3.11 (BrainBox is tested with 3.10-3.13 Python versions):
95
+
96
+ ```commandline
97
+ conda create --name brainbox python==3.11
98
+ ```
99
+
100
+ Then, activate the environment
101
+
102
+ ```commandline
103
+ conda activate brainbox
104
+ ```
105
+
106
+ ## BrainBox
107
+
108
+ Install the brainbox
109
+
110
+ ```commandline
111
+ pip install kaia-brainbox
112
+ ```
113
+
114
+ Run the brainbox
115
+
116
+ ```commandline
117
+ python -m brainbox.run --folder <where_all_files_will_be_stored>
118
+ ```
119
+
120
+
121
+
122
+ # Python's API
123
+
124
+ This is the simplest way to access the BrainBox functionality.
125
+ To use it, simply install BrainBox to your project with `pip install brainbox`
126
+
127
+ ## Basic techniques
128
+
129
+ These are the operations you use for all the deciders all the time you work with BrainBox.
130
+
131
+ To execute the following code, you need to run BrainBox and keep it running.
132
+
133
+ Note, that the code below is also part of the module tests and is located at `/tests/test_readme/`.
134
+ In this documentation, regions from this test are copy-pasted, along with asserts for better understanding of returned values,
135
+ so `test_case` represents a `unittest` TestCase instance.
136
+
137
+ ### Create an API object
138
+
139
+ ```python
140
+ from brainbox import BrainBox
141
+
142
+ api = BrainBox.Api("127.0.0.1:8090")
143
+ api.wait(1)
144
+ ```
145
+
146
+ This will create an API object. `wait` will try to connect to the endpoint
147
+ for 1 second, and raises if unsuccessful.
148
+
149
+ ### Install the decider
150
+
151
+ We have a `Boilerplate` decider, that doesn't do anything useful,
152
+ but accumulates all the features BrainBox has for deciders.
153
+ Let's install the decider:
154
+
155
+ ```python
156
+
157
+ report = api.controller_api.install(Boilerplate)
158
+ test_case.assertIsNotNone(report)
159
+
160
+ ```
161
+
162
+ Note that the container is not pulled, but build on your machine,
163
+ and this is also the case for other deciders.
164
+ This is resource-intensive, in terms of bandwidth and time,
165
+ but allows you to modify the containers quickly
166
+ if you require some model's functionality that wasn't implemented.
167
+ Also it allows BrainBox to work completely independently,
168
+ with the source code only, without reliance to the external
169
+ docker repositories; and finally, it's much easier to check what
170
+ these containers are doing.
171
+
172
+ Returned `report` can largely be ignored, it's only needed for
173
+ GUI purposes.
174
+
175
+ ### Run a self-test
176
+
177
+ The self-tests for the deciders run the most important endpoints,
178
+ and ensure their correct work.
179
+ Also, they provide a report where you can see the inputs and outputs
180
+ for the endpoint, so it is documentation of some sort.
181
+ This report can be viewed as an HTML page.
182
+
183
+ This will run a self-test and opens the result in the web-browser.
184
+
185
+ ```python
186
+
187
+ import requests, webbrowser, tempfile
188
+ from pathlib import Path
189
+
190
+ api.controller_api.self_test(Boilerplate)
191
+ self_test_report = requests.get(f'http://{api.address}/html/controllers/self_test_report/Boilerplate').text
192
+ test_case.assertIsInstance(self_test_report, str)
193
+
194
+ test_case_test_path = Path(tempfile.gettempdir()) / 'test_report.html'
195
+ with open(test_case_test_path, 'w') as file:
196
+ file.write(self_test_report)
197
+
198
+ # webbrowser.open('file://'+str(test_case_test_path))
199
+
200
+ ```
201
+
202
+ While self-test reports provide some understanding of the endpoints,
203
+ I recommend reading the self-tests code: all the endpoints are called
204
+ in the same way you will call them from your Python code.
205
+ Self-tests, building containers and other container-related things
206
+ are performed by `Controller` classes. They are usually located
207
+ within deciders classes, e.g. `Boilerplate.Controller`
208
+
209
+ ### Call an endpoint
210
+
211
+ This will execute the method Boilerplate::json on the server side.
212
+
213
+ ```python
214
+
215
+ result = api.execute(BrainBox.Task.call(Boilerplate).json("Hello"))
216
+ test_case.assertDictEqual(
217
+ {
218
+ 'argument': 'Hello',
219
+ 'model': 'no_parameter',
220
+ 'setting': 'default_setting'
221
+ },
222
+ result
223
+ )
224
+
225
+ ```
226
+
227
+ The BrainBox will run the container for the Boilerplate decider.
228
+ This container has a web-server inside, and Boilerplate::json
229
+ connects to this web-server and performs the required operation.
230
+ The result (in this case, `dict`) is then returned to the caller.
231
+ As you see, `argument` equals to the argument the code provides.
232
+
233
+ BrainBox is smart and tries to minimize the containers' runs.
234
+ If several tasks for same decider have arrived,
235
+ this decider will be set up, and then all these tasks will be executed
236
+ before the tasks for other deciders.
237
+
238
+ ### Call an enpoint with a parameter
239
+
240
+ Few deciders have parameters: a string argument that will be fed to the container
241
+ on the start, and may modify its behaviour. It's sometimes required
242
+ when you don't build container from scratch, but use a ready container,
243
+ which requires you to load the model on the startup, and in this case,
244
+ `parameter` is this model's name.
245
+
246
+ To pass the parameter, simply add it to `call` function:
247
+
248
+ ```python
249
+
250
+ result = api.execute(BrainBox.Task.call(Boilerplate, "parameter").json("Hello"))
251
+ test_case.assertDictEqual(
252
+ {
253
+ 'argument': 'Hello',
254
+ 'model': 'parameter',
255
+ 'setting': 'default_setting'
256
+ },
257
+ result
258
+ )
259
+
260
+ ```
261
+
262
+ As you can see, the `model` field is now set to `parameter`.
263
+
264
+ Most of the deciders do not have the parameter and load models dynamically, so normally you write
265
+ `BrainBoxTask.call(DeciderClass).method(...)`
266
+
267
+ Please ignore the `setting` field.
268
+ There is a possibility to adjust settings to the controllers,
269
+ such as the port the internal web-server will be assigned for,
270
+ or the list of models the controllers need to download,
271
+ but so far there was never a necessity to adjust them manually.
272
+ They are only used with the default values.
273
+
274
+ ### Download files, produced by deciders
275
+
276
+ Many BrainBox deciders return files with generated images or sounds.
277
+ In order not to overload the BrainBox database with all these
278
+ gigabytes, the files are stored in the cache folder,
279
+ and only files' names are returned.
280
+
281
+ ```python
282
+
283
+ filename = api.execute(BrainBox.Task.call(Boilerplate).file("Hello, file!"))
284
+ test_case.assertIsInstance(filename, str)
285
+
286
+ ```
287
+
288
+ You may open this file with `api.open_file` method, which returns `File`
289
+ instance, reading the content of the file on the fly.
290
+
291
+ ```python
292
+
293
+ from brainbox import File
294
+ import json
295
+
296
+ file = api.open_file(filename)
297
+ test_case.assertIsInstance(file, File)
298
+ test_case.assertDictEqual(
299
+ {
300
+ 'argument': 'Hello, file!',
301
+ 'model': 'no_parameter',
302
+ 'setting': 'default_setting'
303
+ },
304
+ json.loads(file.content)
305
+ )
306
+
307
+ ```
308
+
309
+ If you don't want to open the file, only download it on the disk:
310
+
311
+ ```python
312
+ from pathlib import Path
313
+
314
+ path = api.download(filename)
315
+ test_case.assertIsInstance(path, Path)
316
+ with open(path, 'r') as stream:
317
+ test_case.assertDictEqual(
318
+ {
319
+ 'argument': 'Hello, file!',
320
+ 'model': 'no_parameter',
321
+ 'setting': 'default_setting'
322
+ },
323
+ json.load(stream)
324
+ )
325
+
326
+ ```
327
+
328
+ which simply downloads the file on the disk to the given location
329
+ (by default, in the API's cache folder), and returns the full path to file.
330
+ You may specify the location and the flag to redownload the file even
331
+ if it was already downloaded.
332
+
333
+ ### Upload files, required by deciders
334
+
335
+ Some deciders, especially speech-to-text or image analysis,
336
+ use files as inputs. You may feed them directly in the call:
337
+
338
+ ```python
339
+ from brainbox import File
340
+
341
+ file = File('hello.txt', "Hello, world!")
342
+ test_case.assertEqual(file.name, 'hello.txt')
343
+ test_case.assertEqual(file.content, b'Hello, world!')
344
+
345
+ length = api.execute(BrainBox.Task.call(Boilerplate).file_length(file))
346
+ test_case.assertEqual(length, 13)
347
+
348
+ ```
349
+
350
+ However, that has the potential to overload the database as well,
351
+ and should be avoided.
352
+
353
+ If you run BrainBox server at the machine you're running `api`,
354
+ you may pass the path of the file:
355
+
356
+ ```python
357
+
358
+ import tempfile
359
+ from pathlib import Path
360
+
361
+ path = file.write(tempfile.gettempdir())
362
+ test_case.assertIsInstance(path, Path)
363
+
364
+ length = api.execute(BrainBox.Task.call(Boilerplate).file_length(path))
365
+ test_case.assertEqual(length, 13)
366
+
367
+ ```
368
+
369
+ This solution is dirty as it won't work with a remote BrainBox,
370
+ and would force you to rewrite your codebase in case of such change.
371
+
372
+ To avoid this, you may choose to upload the file to the BrainBox
373
+ cache folder instead:
374
+
375
+ ```python
376
+
377
+ api.upload(file.name, file)
378
+ length = api.execute(BrainBox.Task.call(Boilerplate).file_length(file.name))
379
+ test_case.assertEqual(length, 13)
380
+
381
+ ```
382
+
383
+ Sometimes, files are required to have specific names, or some
384
+ recoding. In these cases, deciders usually have static methods
385
+ that incapsulate these procedures in Prerequisites:
386
+
387
+ ```python
388
+ upload_prerequisite = Boilerplate.file_upload(file)
389
+ upload_prerequisite.execute(api)
390
+ length = api.execute(BrainBox.Task.call(Boilerplate).file_length(file.name))
391
+ test_case.assertEqual(length, 13)
392
+
393
+ ```
394
+
395
+ ## Advanced techniques
396
+
397
+ ### Browse the resources
398
+
399
+ Many deciders have _resources_: files, typically model files, that are passed to the containers and used for inference.
400
+ It is impractical to store them inside containers, and so BrainBox stores them in the host's file system:
401
+ each decider has its own resource folder, which is mounted to the container.
402
+
403
+ Aside from models, the training data may be stored in resources instead of file cache, as training data
404
+ are easier to organize with folder structure and predictable filenames.
405
+
406
+ This endpoint demonstrates that the server indeed has an access to the resources:
407
+ Boilerplate reads them and returns the dictionary of keys set to filenames,
408
+ and values set to file content.
409
+ These resources are created by Boilerplate controller as a part of installation procedure.
410
+
411
+ ```python
412
+ resources = api.execute(BrainBox.Task.call(Boilerplate).resources())
413
+ test_case.assertDictEqual(
414
+ {'nested/resource': 'Boilerplate nested resource', 'resource': 'Boilerplate resource'},
415
+ resources
416
+ )
417
+
418
+ ```
419
+
420
+ However, a uniform access to all the resources is provided by API, e.g. to list all the resources:
421
+
422
+ ```python
423
+
424
+ resources = api.controller_api.list_resources(Boilerplate, '/')
425
+ test_case.assertListEqual(
426
+ ['resource', 'nested/resource'],
427
+ resources
428
+ )
429
+
430
+ ```
431
+
432
+ ### Download a custom model
433
+
434
+ Many deciders can run with different models, and these models need to be downloaded.
435
+ All the deciders load some models at the installation time to allow self-test to run.
436
+ However, more models are usually needed.
437
+
438
+ Sometimes the containers are able to download these models themselves,
439
+ but often enough the models need to be downloaded separately.
440
+
441
+ This action can be triggered via `api`:
442
+
443
+ ```python
444
+
445
+ api.controller_api.download_models(Boilerplate, [Boilerplate.Model('google', 'http://www.google.com')])
446
+ resources = api.controller_api.list_resources(Boilerplate, '/models')
447
+ test_case.assertListEqual(['models/google'], resources)
448
+
449
+ ```
450
+
451
+ ### Build a workflow from tasks
452
+
453
+ The output of the tasks can serve as an input to other tasks:
454
+
455
+ ```python
456
+ task1 = BrainBox.Task.call(Boilerplate).json("Hello")
457
+ task2 = BrainBox.Task.call(Boilerplate).json(task1)
458
+ result = api.execute([task1, task2])
459
+ test_case.assertDictEqual(result[0], result[1]['argument'])
460
+
461
+ ```
462
+
463
+ In this case, the `task1` will be executed before `task2` and the output of `task1` will be used
464
+ as an argument for `task2` method.
465
+
466
+ ### Collect the outputs of many tasks
467
+
468
+ One particularly important use case of the dependent tasks is when
469
+ several tasks are run, each associated with some __tags__ describing a task,
470
+ and then the outputs of all tasks are collected together and returned as a single entity.
471
+
472
+ `Collector` does just this. Declaring collector tasks in a raw form is very cumbersome,
473
+ and we actually use helpers to do this,
474
+ however, it helps to see what's going on under the hood.
475
+
476
+ ```python
477
+ from brainbox.deciders import Collector
478
+ from brainbox import BrainBoxCombinedTask
479
+
480
+ id1 = 'id_1'
481
+ id2 = 'id_2'
482
+ task1 = BrainBox.Task.call(Boilerplate).json(0).to_task(id=id1)
483
+ task2 = BrainBox.Task.call(Boilerplate).json(1).to_task(id=id2)
484
+ collector = BrainBox.Task.call(Collector).to_array(
485
+ tags = {id1: dict(index=0), id2: dict(index=1)},
486
+ ** {
487
+ id1: task1,
488
+ id2: task2
489
+ }
490
+ )
491
+ pack = BrainBoxCombinedTask(
492
+ resulting_task = collector,
493
+ intermediate_tasks = (task1, task2)
494
+ )
495
+ array = api.execute(pack)
496
+
497
+ ```
498
+
499
+ We can shorten this significantly with `Collector.TaskBuilder`:
500
+
501
+ ```python
502
+
503
+ builder = Collector.TaskBuilder()
504
+ for i in range(10):
505
+ builder.append(task=BrainBox.Task.call(Boilerplate).json(i), tags=dict(index=i))
506
+ pack = builder.to_collector_pack('to_array')
507
+ array = api.execute(pack)
508
+
509
+ ```
510
+
511
+ ### Collect the files from many tasks
512
+
513
+ One problem remains: if deciders return files, these files won't be collected.
514
+ To solve it, MediaLibrary structure is used. Essentially it's a zip-file
515
+ that contains all the outputs as well as tags.
516
+
517
+ ```python
518
+ from brainbox import MediaLibrary
519
+ from brainbox.deciders import Collector
520
+ import json
521
+
522
+ builder = Collector.TaskBuilder()
523
+ for i in range(10):
524
+ builder.append(task=BrainBox.Task.call(Boilerplate).file(i), tags=dict(index=i))
525
+ pack = builder.to_collector_pack('to_media_library')
526
+ path = api.download(api.execute(pack))
527
+ ml = MediaLibrary.read(path)
528
+ for record in ml.records:
529
+ content = record.get_content()
530
+ tags = record.tags
531
+ test_case.assertEqual(tags['index'], json.loads(content)['argument'])
532
+
533
+ ```
534
+
535
+ # Use it without Python
536
+
537
+ All the BrainBox functionality is accessible without Python API, with direct HTTP requests.
538
+ Since Python API actually works over the HTTP requests to BrainBox server,
539
+ and the API calls are translated into HTTP requests automatically with `brainbox.framework.common.marshalling` module,
540
+ I can guarantee that it works.
541
+ However, it is not yet nicely documented.
542
+
543
+ ## Manage the controllers
544
+
545
+ Installation, running, stopping and self-testing of deciders is available on
546
+ `http://127.0.0.1:8090/html/controllers/status`.
547
+ The web-page is hopefully self-explanatory.
548
+
549
+ The web-page also allows you to start the container.
550
+ Since most of the containers have web-server inside, you can call the endpoints of these web-servers
551
+ instead of BrainBox.
552
+ These servers, however, are not nicely written, don't have the documentation
553
+ and there is no plan to write this documentation in the future,
554
+ because it's a massive work that will have little sense,
555
+ since BrainBox implements the calls itself.
556
+
557
+ ## Run the tasks
558
+
559
+ To run the deciders via BrainBox, we have two endpoints, `/jobs/add` and `/jobs/join`.
560
+
561
+ `jobs/add` accepts a list of dictionaries, each describing one job.
562
+ What we did above with `BrainBox.Task.call(Boilerplate)` was actually a definition of the job with API.
563
+ Job has the following fields:
564
+
565
+ * `id`: a unique string id of the job
566
+ * `decider`: the name of the decider, like `"Boilerlate"` string
567
+ * `method`: the method of decider class we're running. Can be None if the class defines `__call__` method and is therefore callable itself.
568
+ * `decider_parameter`: decider's parameter, usually None
569
+ * `arguments`: arguments of the method as dictionary.
570
+ * `info`: arbitrary data that is associated with the job, but doesn't have any effect on it.
571
+ * `batch`: jobs in e.g. `Collector`'s packs are organized in batches, so in the web-interface it may be seen what percentage
572
+ of this collective job is finished.
573
+ * `dependencies`: a dictionary with keys set to the names of the arguments of the method, and values as id of the dependent tasks.
574
+ If the key starts with `*`, the dependent task will be waited for, but it's value won't be used.
575
+ * `ordering_token`: None or an arbitrary string that helps BrainBox arrange the jobs to minimize the model switching.
576
+ Something like `<larger_model_name>/<smaller_model_name>/<even_smaller_model_name>` is usually sufficient.
577
+
578
+ Simply the list of such dictionaries to the BrainBox server and it will add the tasks to the queue,
579
+ returning the control immediately.
580
+ To block your process until the tasks are finished, use `/jobs/join` endpoint,
581
+ and provide it with the list of `id` of the jobs you want to wait for.
582
+ As a result, `/jobs/join` will return a list of arbitrary objects that correspond to the list of `id`.
583
+
584
+ ```python
585
+ import requests
586
+ import uuid
587
+
588
+ address = api.address
589
+ id = str(uuid.uuid4())
590
+
591
+ reply = requests.post(f'http://{address}/jobs/add', json=
592
+ {
593
+ "arguments": {
594
+ "jobs": [
595
+ {
596
+ "id": id,
597
+ "decider": "Boilerplate",
598
+ "method": "json",
599
+ "decider_parameter": None,
600
+ "arguments": {
601
+ "argument": "Hello, HTTP"
602
+ }
603
+ }
604
+ ]
605
+ }
606
+ })
607
+ if reply.status_code != 200:
608
+ raise ValueError(f"Endpoint returned {reply.status_code}\n{reply.json()['error']}")
609
+
610
+ reply = requests.get(f"http://{address}/jobs/join", json=
611
+ {
612
+ "arguments": {
613
+ "ids": [
614
+ id
615
+ ]
616
+ }
617
+ })
618
+
619
+ if reply.status_code != 200:
620
+ raise ValueError(f"Endpoint returned {reply.status_code}\n{reply.json()['error']}")
621
+
622
+ result = reply.json()['result'][0]
623
+ test_case.assertDictEqual(
624
+ {
625
+ 'argument': 'Hello, HTTP',
626
+ 'model': 'no_parameter',
627
+ 'setting': 'default_setting'
628
+ },
629
+ result
630
+ )
631
+ ```
632
+
633
+
634
+
635
+
636
+
637
+