reachy-mini 1.2.5rc1__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.
Files changed (479) hide show
  1. reachy_mini/__init__.py +4 -0
  2. reachy_mini/apps/__init__.py +25 -0
  3. reachy_mini/apps/app.py +258 -0
  4. reachy_mini/apps/assistant.py +787 -0
  5. reachy_mini/apps/manager.py +312 -0
  6. reachy_mini/apps/sources/__init__.py +4 -0
  7. reachy_mini/apps/sources/hf_space.py +106 -0
  8. reachy_mini/apps/sources/local_common_venv.py +567 -0
  9. reachy_mini/apps/templates/README.md.j2 +12 -0
  10. reachy_mini/apps/templates/gitignore.j2 +3 -0
  11. reachy_mini/apps/templates/index.html.j2 +40 -0
  12. reachy_mini/apps/templates/main.py.j2 +74 -0
  13. reachy_mini/apps/templates/pyproject.toml.j2 +28 -0
  14. reachy_mini/apps/templates/static/index.html.j2 +27 -0
  15. reachy_mini/apps/templates/static/main.js.j2 +47 -0
  16. reachy_mini/apps/templates/static/style.css.j2 +25 -0
  17. reachy_mini/apps/templates/style.css.j2 +411 -0
  18. reachy_mini/apps/utils.py +30 -0
  19. reachy_mini/assets/config/hardware_config.yaml +164 -0
  20. reachy_mini/assets/confused1.wav +0 -0
  21. reachy_mini/assets/count.wav +0 -0
  22. reachy_mini/assets/dance1.wav +0 -0
  23. reachy_mini/assets/firmware/CHANGELOG.md +15 -0
  24. reachy_mini/assets/firmware/reachymini_ua_io16_lin_v2.1.2.bin +0 -0
  25. reachy_mini/assets/firmware/reachymini_ua_io16_lin_v2.1.3.bin +0 -0
  26. reachy_mini/assets/firmware/update.sh +9 -0
  27. reachy_mini/assets/go_sleep.wav +0 -0
  28. reachy_mini/assets/impatient1.wav +0 -0
  29. reachy_mini/assets/kinematics_data.json +253 -0
  30. reachy_mini/assets/models/fknetwork.dynamic.onnx +0 -0
  31. reachy_mini/assets/models/fknetwork.onnx +0 -0
  32. reachy_mini/assets/models/fknetwork_int8.onnx +0 -0
  33. reachy_mini/assets/models/iknetwork.onnx +0 -0
  34. reachy_mini/assets/wake_up.wav +0 -0
  35. reachy_mini/daemon/__init__.py +1 -0
  36. reachy_mini/daemon/app/__init__.py +1 -0
  37. reachy_mini/daemon/app/bg_job_register.py +142 -0
  38. reachy_mini/daemon/app/dashboard/static/assets/KO-cartoon-static.svg +40 -0
  39. reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon-static.svg +42 -0
  40. reachy_mini/daemon/app/dashboard/static/assets/awake-cartoon.svg +6 -0
  41. reachy_mini/daemon/app/dashboard/static/assets/go-to-sleep-cartoon.svg +6 -0
  42. reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon-static.svg +50 -0
  43. reachy_mini/daemon/app/dashboard/static/assets/no-wifi-cartoon.svg +6 -0
  44. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-awake.svg +18 -0
  45. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-connection-lost-animation.svg +6 -0
  46. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-go-to-sleep-animation.svg +6 -0
  47. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko-animation.svg +6 -0
  48. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-ko.svg +22 -0
  49. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping-static.svg +41 -0
  50. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-sleeping.svg +18 -0
  51. reachy_mini/daemon/app/dashboard/static/assets/reachy-mini-wake-up-animation.svg +6 -0
  52. reachy_mini/daemon/app/dashboard/static/css/app.css +1433 -0
  53. reachy_mini/daemon/app/dashboard/static/fonts/Archivo-Italic-VariableFont_wdth,wght.ttf +0 -0
  54. reachy_mini/daemon/app/dashboard/static/fonts/Archivo-VariableFont_wdth,wght.ttf +0 -0
  55. reachy_mini/daemon/app/dashboard/static/fonts/Asap-Italic-VariableFont_wdth,wght.ttf +0 -0
  56. reachy_mini/daemon/app/dashboard/static/fonts/Asap-VariableFont_wdth,wght.ttf +0 -0
  57. reachy_mini/daemon/app/dashboard/static/js/3rdparty/gstwebrtc-api-2.0.0.min.js +5 -0
  58. reachy_mini/daemon/app/dashboard/static/js/apps.js +323 -0
  59. reachy_mini/daemon/app/dashboard/static/js/appstore.js +167 -0
  60. reachy_mini/daemon/app/dashboard/static/js/daemon.js +169 -0
  61. reachy_mini/daemon/app/dashboard/static/js/health_check.js +9 -0
  62. reachy_mini/daemon/app/dashboard/static/js/move_player.js +132 -0
  63. reachy_mini/daemon/app/dashboard/static/js/notification.js +41 -0
  64. reachy_mini/daemon/app/dashboard/static/js/update.js +132 -0
  65. reachy_mini/daemon/app/dashboard/static/js/volume_control.js +252 -0
  66. reachy_mini/daemon/app/dashboard/static/js/wifi.js +176 -0
  67. reachy_mini/daemon/app/dashboard/tailwindcss/README.md +15 -0
  68. reachy_mini/daemon/app/dashboard/tailwindcss/package-lock.json +1127 -0
  69. reachy_mini/daemon/app/dashboard/tailwindcss/package.json +6 -0
  70. reachy_mini/daemon/app/dashboard/tailwindcss/pnpm-lock.yaml +608 -0
  71. reachy_mini/daemon/app/dashboard/tailwindcss/postcss.config.js +6 -0
  72. reachy_mini/daemon/app/dashboard/tailwindcss/styles/app.css +185 -0
  73. reachy_mini/daemon/app/dashboard/tailwindcss/tailwind.config.js +11 -0
  74. reachy_mini/daemon/app/dashboard/templates/base.html +21 -0
  75. reachy_mini/daemon/app/dashboard/templates/index.html +20 -0
  76. reachy_mini/daemon/app/dashboard/templates/sections/apps.html +8 -0
  77. reachy_mini/daemon/app/dashboard/templates/sections/appstore.html +35 -0
  78. reachy_mini/daemon/app/dashboard/templates/sections/daemon.html +45 -0
  79. reachy_mini/daemon/app/dashboard/templates/sections/move_player.html +121 -0
  80. reachy_mini/daemon/app/dashboard/templates/sections/notification.html +19 -0
  81. reachy_mini/daemon/app/dashboard/templates/sections/update.html +54 -0
  82. reachy_mini/daemon/app/dashboard/templates/sections/wifi.html +46 -0
  83. reachy_mini/daemon/app/dashboard/templates/settings.html +14 -0
  84. reachy_mini/daemon/app/dependencies.py +41 -0
  85. reachy_mini/daemon/app/main.py +469 -0
  86. reachy_mini/daemon/app/models.py +149 -0
  87. reachy_mini/daemon/app/routers/apps.py +114 -0
  88. reachy_mini/daemon/app/routers/daemon.py +85 -0
  89. reachy_mini/daemon/app/routers/kinematics.py +57 -0
  90. reachy_mini/daemon/app/routers/motors.py +41 -0
  91. reachy_mini/daemon/app/routers/move.py +265 -0
  92. reachy_mini/daemon/app/routers/state.py +146 -0
  93. reachy_mini/daemon/app/routers/update.py +86 -0
  94. reachy_mini/daemon/app/routers/volume.py +423 -0
  95. reachy_mini/daemon/app/routers/wifi_config.py +219 -0
  96. reachy_mini/daemon/app/services/__init__.py +1 -0
  97. reachy_mini/daemon/app/services/bluetooth/bluetooth_service.py +796 -0
  98. reachy_mini/daemon/app/services/bluetooth/commands/HOTSPOT.sh +7 -0
  99. reachy_mini/daemon/app/services/bluetooth/commands/RESTART_DAEMON.sh +4 -0
  100. reachy_mini/daemon/app/services/bluetooth/commands/SOFTWARE_RESET.sh +7 -0
  101. reachy_mini/daemon/app/services/bluetooth/install_service_bluetooth.sh +39 -0
  102. reachy_mini/daemon/app/services/gpio_shutdown/__init__.py +1 -0
  103. reachy_mini/daemon/app/services/gpio_shutdown/install_service.sh +33 -0
  104. reachy_mini/daemon/app/services/gpio_shutdown/launcher.sh +3 -0
  105. reachy_mini/daemon/app/services/gpio_shutdown/shutdown_monitor.py +28 -0
  106. reachy_mini/daemon/app/services/wireless/generate_asoundrc.sh +70 -0
  107. reachy_mini/daemon/app/services/wireless/install_service.sh +33 -0
  108. reachy_mini/daemon/app/services/wireless/launcher.sh +5 -0
  109. reachy_mini/daemon/backend/__init__.py +1 -0
  110. reachy_mini/daemon/backend/abstract.py +815 -0
  111. reachy_mini/daemon/backend/mujoco/__init__.py +36 -0
  112. reachy_mini/daemon/backend/mujoco/backend.py +395 -0
  113. reachy_mini/daemon/backend/mujoco/utils.py +59 -0
  114. reachy_mini/daemon/backend/mujoco/video_udp.py +57 -0
  115. reachy_mini/daemon/backend/robot/__init__.py +8 -0
  116. reachy_mini/daemon/backend/robot/backend.py +597 -0
  117. reachy_mini/daemon/daemon.py +651 -0
  118. reachy_mini/daemon/utils.py +116 -0
  119. reachy_mini/descriptions/reachy_mini/mjcf/additional.xml +6 -0
  120. reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.part +13 -0
  121. reachy_mini/descriptions/reachy_mini/mjcf/assets/5w_speaker.stl +0 -0
  122. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.part +13 -0
  123. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna.stl +0 -0
  124. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.part +13 -0
  125. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_body_3dprint.stl +0 -0
  126. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.part +13 -0
  127. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_l_3dprint.stl +0 -0
  128. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.part +13 -0
  129. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_holder_r_3dprint.stl +0 -0
  130. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.part +13 -0
  131. reachy_mini/descriptions/reachy_mini/mjcf/assets/antenna_interface_3dprint.stl +0 -0
  132. reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.part +13 -0
  133. reachy_mini/descriptions/reachy_mini/mjcf/assets/arducam.stl +0 -0
  134. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.part +13 -0
  135. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh.stl +0 -0
  136. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.part +13 -0
  137. reachy_mini/descriptions/reachy_mini/mjcf/assets/b3b_eh_1.stl +0 -0
  138. reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.part +13 -0
  139. reachy_mini/descriptions/reachy_mini/mjcf/assets/bearing_85x110x13.stl +0 -0
  140. reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.part +13 -0
  141. reachy_mini/descriptions/reachy_mini/mjcf/assets/big_lens_d40.stl +0 -0
  142. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.part +13 -0
  143. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_down_3dprint.stl +0 -0
  144. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.part +13 -0
  145. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_foot_3dprint.stl +0 -0
  146. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.part +13 -0
  147. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_top_3dprint.stl +0 -0
  148. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.part +13 -0
  149. reachy_mini/descriptions/reachy_mini/mjcf/assets/body_turning_3dprint.stl +0 -0
  150. reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.part +13 -0
  151. reachy_mini/descriptions/reachy_mini/mjcf/assets/bts2_m2_6x8.stl +0 -0
  152. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/README.m +1 -0
  153. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_0.stl +0 -0
  154. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_1.stl +0 -0
  155. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_2.stl +0 -0
  156. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_back_3.stl +0 -0
  157. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_0.stl +0 -0
  158. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_1.stl +0 -0
  159. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/body_top_3dprint_collider_front_2.stl +0 -0
  160. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/coarse/head_one_3dprint_collider_0.stl +0 -0
  161. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_0.stl +0 -0
  162. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_1.stl +0 -0
  163. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_2.stl +0 -0
  164. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_back_3.stl +0 -0
  165. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_0.stl +0 -0
  166. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_1.stl +0 -0
  167. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/body_top_3dprint_collider_front_2.stl +0 -0
  168. reachy_mini/descriptions/reachy_mini/mjcf/assets/collision/fine/head_one_3dprint_collider_0.stl +0 -0
  169. reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/croissant_1k.obj +5021 -0
  170. reachy_mini/descriptions/reachy_mini/mjcf/assets/croissant_1k.blend/textures/croissant_diff_1k.png +0 -0
  171. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.part +13 -0
  172. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_b_dummy.stl +0 -0
  173. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.part +13 -0
  174. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_f_dummy.stl +0 -0
  175. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.part +13 -0
  176. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_case_m_dummy.stl +0 -0
  177. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.part +13 -0
  178. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_horn_dummy.stl +0 -0
  179. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.part +13 -0
  180. reachy_mini/descriptions/reachy_mini/mjcf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
  181. reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/food_apple_01_1k.obj +18045 -0
  182. reachy_mini/descriptions/reachy_mini/mjcf/assets/food_apple_01_1k.blend/textures/food_apple_01_diff_1k.png +0 -0
  183. reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.part +13 -0
  184. reachy_mini/descriptions/reachy_mini/mjcf/assets/glasses_dolder_3dprint.stl +0 -0
  185. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.part +13 -0
  186. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_back_3dprint.stl +0 -0
  187. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.part +13 -0
  188. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_front_3dprint.stl +0 -0
  189. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.part +13 -0
  190. reachy_mini/descriptions/reachy_mini/mjcf/assets/head_mic_3dprint.stl +0 -0
  191. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.part +13 -0
  192. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d30_3dprint.stl +0 -0
  193. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.part +13 -0
  194. reachy_mini/descriptions/reachy_mini/mjcf/assets/lens_cap_d40_3dprint.stl +0 -0
  195. reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.part +13 -0
  196. reachy_mini/descriptions/reachy_mini/mjcf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
  197. reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.part +13 -0
  198. reachy_mini/descriptions/reachy_mini/mjcf/assets/mp01062_stewart_arm_3.stl +0 -0
  199. reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.part +13 -0
  200. reachy_mini/descriptions/reachy_mini/mjcf/assets/neck_reference_3dprint.stl +0 -0
  201. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.part +13 -0
  202. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10.stl +0 -0
  203. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.part +13 -0
  204. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
  205. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.part +13 -0
  206. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
  207. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.part +13 -0
  208. reachy_mini/descriptions/reachy_mini/mjcf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
  209. reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.part +13 -0
  210. reachy_mini/descriptions/reachy_mini/mjcf/assets/pp01102_arducam_carter.stl +0 -0
  211. reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/rubber_duck_toy_1k.obj +8940 -0
  212. reachy_mini/descriptions/reachy_mini/mjcf/assets/rubber_duck_toy_1k.blend/textures/rubber_duck_toy_diff_1k.png +0 -0
  213. reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.part +13 -0
  214. reachy_mini/descriptions/reachy_mini/mjcf/assets/small_lens_d30.stl +0 -0
  215. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.part +13 -0
  216. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball.stl +0 -0
  217. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.part +13 -0
  218. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_ball__2.stl +0 -0
  219. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.part +13 -0
  220. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_link_rod.stl +0 -0
  221. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.part +13 -0
  222. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_main_plate_3dprint.stl +0 -0
  223. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.part +13 -0
  224. reachy_mini/descriptions/reachy_mini/mjcf/assets/stewart_tricap_3dprint.stl +0 -0
  225. reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/textures/wooden_table_02_diff_1k.png +0 -0
  226. reachy_mini/descriptions/reachy_mini/mjcf/assets/wooden_table_02_1k.blend/wooden_table_02_1k.obj +485 -0
  227. reachy_mini/descriptions/reachy_mini/mjcf/config.json +21 -0
  228. reachy_mini/descriptions/reachy_mini/mjcf/joints_properties.xml +29 -0
  229. reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml +642 -0
  230. reachy_mini/descriptions/reachy_mini/mjcf/reachy_mini.xml.bak +442 -0
  231. reachy_mini/descriptions/reachy_mini/mjcf/scene.xml +24 -0
  232. reachy_mini/descriptions/reachy_mini/mjcf/scenes/empty.xml +27 -0
  233. reachy_mini/descriptions/reachy_mini/mjcf/scenes/minimal.xml +132 -0
  234. reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.part +13 -0
  235. reachy_mini/descriptions/reachy_mini/urdf/assets/5w_speaker.stl +0 -0
  236. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.part +13 -0
  237. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna.stl +0 -0
  238. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.part +13 -0
  239. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_body_3dprint.stl +0 -0
  240. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.part +13 -0
  241. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_l_3dprint.stl +0 -0
  242. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.part +13 -0
  243. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_holder_r_3dprint.stl +0 -0
  244. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.part +13 -0
  245. reachy_mini/descriptions/reachy_mini/urdf/assets/antenna_interface_3dprint.stl +0 -0
  246. reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.part +13 -0
  247. reachy_mini/descriptions/reachy_mini/urdf/assets/arducam.stl +0 -0
  248. reachy_mini/descriptions/reachy_mini/urdf/assets/arm.part +13 -0
  249. reachy_mini/descriptions/reachy_mini/urdf/assets/arm.stl +0 -0
  250. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.part +13 -0
  251. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh.stl +0 -0
  252. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.part +13 -0
  253. reachy_mini/descriptions/reachy_mini/urdf/assets/b3b_eh_1.stl +0 -0
  254. reachy_mini/descriptions/reachy_mini/urdf/assets/ball.part +13 -0
  255. reachy_mini/descriptions/reachy_mini/urdf/assets/ball.stl +0 -0
  256. reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.part +13 -0
  257. reachy_mini/descriptions/reachy_mini/urdf/assets/bearing_85x110x13.stl +0 -0
  258. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.part +13 -0
  259. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens.stl +0 -0
  260. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.part +13 -0
  261. reachy_mini/descriptions/reachy_mini/urdf/assets/big_lens_d40.stl +0 -0
  262. reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.part +13 -0
  263. reachy_mini/descriptions/reachy_mini/urdf/assets/body_down_3dprint.stl +0 -0
  264. reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.part +13 -0
  265. reachy_mini/descriptions/reachy_mini/urdf/assets/body_foot_3dprint.stl +0 -0
  266. reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.part +13 -0
  267. reachy_mini/descriptions/reachy_mini/urdf/assets/body_top_3dprint.stl +0 -0
  268. reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.part +13 -0
  269. reachy_mini/descriptions/reachy_mini/urdf/assets/body_turning_3dprint.stl +0 -0
  270. reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.part +13 -0
  271. reachy_mini/descriptions/reachy_mini/urdf/assets/bottom_body.stl +0 -0
  272. reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.part +13 -0
  273. reachy_mini/descriptions/reachy_mini/urdf/assets/bts2_m2_6x8.stl +0 -0
  274. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/README.m +1 -0
  275. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_0.stl +0 -0
  276. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_1.stl +0 -0
  277. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_2.stl +0 -0
  278. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_back_3.stl +0 -0
  279. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_0.stl +0 -0
  280. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_1.stl +0 -0
  281. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/body_top_3dprint_collider_front_2.stl +0 -0
  282. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/coarse/head_one_3dprint_collider_0.stl +0 -0
  283. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_0.stl +0 -0
  284. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_1.stl +0 -0
  285. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_2.stl +0 -0
  286. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_back_3.stl +0 -0
  287. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_0.stl +0 -0
  288. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_1.stl +0 -0
  289. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/body_top_3dprint_collider_front_2.stl +0 -0
  290. reachy_mini/descriptions/reachy_mini/urdf/assets/collision/fine/head_one_3dprint_collider_0.stl +0 -0
  291. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.part +13 -0
  292. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_b_dummy.stl +0 -0
  293. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.part +13 -0
  294. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_f_dummy.stl +0 -0
  295. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.part +13 -0
  296. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_case_m_dummy.stl +0 -0
  297. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.part +13 -0
  298. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_horn_dummy.stl +0 -0
  299. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.part +13 -0
  300. reachy_mini/descriptions/reachy_mini/urdf/assets/dc15_a01_led_cap2_dummy.stl +0 -0
  301. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.part +14 -0
  302. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_default.stl +0 -0
  303. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.part +14 -0
  304. reachy_mini/descriptions/reachy_mini/urdf/assets/drive_palonier__configuration_simple_axe.stl +0 -0
  305. reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.part +13 -0
  306. reachy_mini/descriptions/reachy_mini/urdf/assets/eye_support.stl +0 -0
  307. reachy_mini/descriptions/reachy_mini/urdf/assets/foot.part +13 -0
  308. reachy_mini/descriptions/reachy_mini/urdf/assets/foot.stl +0 -0
  309. reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.part +13 -0
  310. reachy_mini/descriptions/reachy_mini/urdf/assets/glasses_dolder_3dprint.stl +0 -0
  311. reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.part +13 -0
  312. reachy_mini/descriptions/reachy_mini/urdf/assets/head_back_3dprint.stl +0 -0
  313. reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.part +13 -0
  314. reachy_mini/descriptions/reachy_mini/urdf/assets/head_front_3dprint.stl +0 -0
  315. reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.part +13 -0
  316. reachy_mini/descriptions/reachy_mini/urdf/assets/head_head_back.stl +0 -0
  317. reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.part +13 -0
  318. reachy_mini/descriptions/reachy_mini/urdf/assets/head_interface.stl +0 -0
  319. reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.part +13 -0
  320. reachy_mini/descriptions/reachy_mini/urdf/assets/head_mic_3dprint.stl +0 -0
  321. reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.part +13 -0
  322. reachy_mini/descriptions/reachy_mini/urdf/assets/head_shell_front.stl +0 -0
  323. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.part +13 -0
  324. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d30_3dprint.stl +0 -0
  325. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.part +13 -0
  326. reachy_mini/descriptions/reachy_mini/urdf/assets/lens_cap_d40_3dprint.stl +0 -0
  327. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.part +13 -0
  328. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_fisheye_lens_1_8mm.stl +0 -0
  329. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.part +13 -0
  330. reachy_mini/descriptions/reachy_mini/urdf/assets/m12_lens.stl +0 -0
  331. reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.part +13 -0
  332. reachy_mini/descriptions/reachy_mini/urdf/assets/main_plate.stl +0 -0
  333. reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.part +13 -0
  334. reachy_mini/descriptions/reachy_mini/urdf/assets/mid_plate.stl +0 -0
  335. reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.part +13 -0
  336. reachy_mini/descriptions/reachy_mini/urdf/assets/mp01062_stewart_arm_3.stl +0 -0
  337. reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.part +13 -0
  338. reachy_mini/descriptions/reachy_mini/urdf/assets/neck_reference_3dprint.stl +0 -0
  339. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.part +13 -0
  340. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10.stl +0 -0
  341. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.part +13 -0
  342. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_1.stl +0 -0
  343. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.part +13 -0
  344. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_2.stl +0 -0
  345. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.part +13 -0
  346. reachy_mini/descriptions/reachy_mini/urdf/assets/phs_1_7x20_5_dc10_3.stl +0 -0
  347. reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.part +13 -0
  348. reachy_mini/descriptions/reachy_mini/urdf/assets/plateform.stl +0 -0
  349. reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.part +13 -0
  350. reachy_mini/descriptions/reachy_mini/urdf/assets/pp00xxx_stewart_rod.stl +0 -0
  351. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.part +13 -0
  352. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01062_stewart_arm.stl +0 -0
  353. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.part +13 -0
  354. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01063_stewart_plateform.stl +0 -0
  355. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.part +13 -0
  356. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01064_stewart_main_plate.stl +0 -0
  357. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.part +13 -0
  358. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01065_stewart_side_plate.stl +0 -0
  359. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.part +13 -0
  360. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01066_stewart_mid_plate.stl +0 -0
  361. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.part +13 -0
  362. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01067_bottom_body.stl +0 -0
  363. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.part +13 -0
  364. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01068_top_body.stl +0 -0
  365. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.part +13 -0
  366. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01069_head_shell_front.stl +0 -0
  367. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.part +13 -0
  368. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01070_head_head_back.stl +0 -0
  369. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.part +13 -0
  370. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01071_turning_bowl.stl +0 -0
  371. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.part +13 -0
  372. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01072_turning_end.stl +0 -0
  373. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.part +13 -0
  374. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01078_glasses.stl +0 -0
  375. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.part +13 -0
  376. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01079_back_big_eye.stl +0 -0
  377. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.part +13 -0
  378. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01080_back_small_eye.stl +0 -0
  379. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.part +13 -0
  380. reachy_mini/descriptions/reachy_mini/urdf/assets/pp01102_arducam_carter.stl +0 -0
  381. reachy_mini/descriptions/reachy_mini/urdf/assets/rod.part +13 -0
  382. reachy_mini/descriptions/reachy_mini/urdf/assets/rod.stl +0 -0
  383. reachy_mini/descriptions/reachy_mini/urdf/assets/shape.part +13 -0
  384. reachy_mini/descriptions/reachy_mini/urdf/assets/shape.stl +0 -0
  385. reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.part +13 -0
  386. reachy_mini/descriptions/reachy_mini/urdf/assets/side_plate.stl +0 -0
  387. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.part +13 -0
  388. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens.stl +0 -0
  389. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.part +13 -0
  390. reachy_mini/descriptions/reachy_mini/urdf/assets/small_lens_d30.stl +0 -0
  391. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.part +13 -0
  392. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball.stl +0 -0
  393. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.part +13 -0
  394. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_ball__2.stl +0 -0
  395. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.part +13 -0
  396. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_link_rod.stl +0 -0
  397. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.part +13 -0
  398. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_main_plate_3dprint.stl +0 -0
  399. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.part +13 -0
  400. reachy_mini/descriptions/reachy_mini/urdf/assets/stewart_tricap_3dprint.stl +0 -0
  401. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.part +13 -0
  402. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna.stl +0 -0
  403. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.part +13 -0
  404. reachy_mini/descriptions/reachy_mini/urdf/assets/test_antenna_body.stl +0 -0
  405. reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.part +13 -0
  406. reachy_mini/descriptions/reachy_mini/urdf/assets/top_body.stl +0 -0
  407. reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.part +13 -0
  408. reachy_mini/descriptions/reachy_mini/urdf/assets/turning_bowl.stl +0 -0
  409. reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.part +13 -0
  410. reachy_mini/descriptions/reachy_mini/urdf/assets/uc_a37_rev_a_step.stl +0 -0
  411. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.part +14 -0
  412. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_default.stl +0 -0
  413. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.part +14 -0
  414. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0122topcabinetcase_95__configuration_simple_axe.stl +0 -0
  415. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.part +14 -0
  416. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_default.stl +0 -0
  417. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.part +14 -0
  418. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0123middlecase_56__configuration_simple_axe.stl +0 -0
  419. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.part +14 -0
  420. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_default.stl +0 -0
  421. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.part +14 -0
  422. reachy_mini/descriptions/reachy_mini/urdf/assets/wj_wk00_0124bottomcase_45__configuration_simple_axe.stl +0 -0
  423. reachy_mini/descriptions/reachy_mini/urdf/config.json +18 -0
  424. reachy_mini/descriptions/reachy_mini/urdf/robot.urdf +3281 -0
  425. reachy_mini/descriptions/reachy_mini/urdf/robot.urdf.bak +3282 -0
  426. reachy_mini/descriptions/reachy_mini/urdf/robot_no_collision.urdf +2316 -0
  427. reachy_mini/descriptions/reachy_mini/urdf/robot_simple_collision.urdf +2399 -0
  428. reachy_mini/io/__init__.py +15 -0
  429. reachy_mini/io/abstract.py +70 -0
  430. reachy_mini/io/audio_ws.py +242 -0
  431. reachy_mini/io/protocol.py +44 -0
  432. reachy_mini/io/video_ws.py +135 -0
  433. reachy_mini/io/ws_controller.py +120 -0
  434. reachy_mini/io/zenoh_client.py +273 -0
  435. reachy_mini/io/zenoh_server.py +230 -0
  436. reachy_mini/kinematics/__init__.py +68 -0
  437. reachy_mini/kinematics/analytical_kinematics.py +151 -0
  438. reachy_mini/kinematics/nn_kinematics.py +109 -0
  439. reachy_mini/kinematics/placo_kinematics.py +656 -0
  440. reachy_mini/media/__init__.py +1 -0
  441. reachy_mini/media/audio_base.py +111 -0
  442. reachy_mini/media/audio_control_utils.py +455 -0
  443. reachy_mini/media/audio_gstreamer.py +272 -0
  444. reachy_mini/media/audio_sounddevice.py +321 -0
  445. reachy_mini/media/audio_utils.py +114 -0
  446. reachy_mini/media/camera_base.py +100 -0
  447. reachy_mini/media/camera_constants.py +152 -0
  448. reachy_mini/media/camera_gstreamer.py +231 -0
  449. reachy_mini/media/camera_opencv.py +89 -0
  450. reachy_mini/media/camera_utils.py +111 -0
  451. reachy_mini/media/media_manager.py +281 -0
  452. reachy_mini/media/webrtc_client_gstreamer.py +288 -0
  453. reachy_mini/media/webrtc_daemon.py +334 -0
  454. reachy_mini/motion/__init__.py +4 -0
  455. reachy_mini/motion/goto.py +71 -0
  456. reachy_mini/motion/move.py +43 -0
  457. reachy_mini/motion/recorded_move.py +146 -0
  458. reachy_mini/reachy_mini.py +753 -0
  459. reachy_mini/tools/reflash_motors.py +116 -0
  460. reachy_mini/tools/setup_motor.py +422 -0
  461. reachy_mini/tools/setup_motor_rpi.py +108 -0
  462. reachy_mini/utils/__init__.py +46 -0
  463. reachy_mini/utils/constants.py +9 -0
  464. reachy_mini/utils/hardware_config/__init__.py +1 -0
  465. reachy_mini/utils/hardware_config/parser.py +65 -0
  466. reachy_mini/utils/interpolation.py +227 -0
  467. reachy_mini/utils/parse_urdf_for_kinematics.py +110 -0
  468. reachy_mini/utils/rerun.py +320 -0
  469. reachy_mini/utils/wireless_version/__init__.py +1 -0
  470. reachy_mini/utils/wireless_version/startup_check.py +144 -0
  471. reachy_mini/utils/wireless_version/update.py +20 -0
  472. reachy_mini/utils/wireless_version/update_available.py +61 -0
  473. reachy_mini/utils/wireless_version/utils.py +39 -0
  474. reachy_mini-1.2.5rc1.dist-info/METADATA +161 -0
  475. reachy_mini-1.2.5rc1.dist-info/RECORD +479 -0
  476. reachy_mini-1.2.5rc1.dist-info/WHEEL +5 -0
  477. reachy_mini-1.2.5rc1.dist-info/entry_points.txt +4 -0
  478. reachy_mini-1.2.5rc1.dist-info/licenses/LICENSE +201 -0
  479. reachy_mini-1.2.5rc1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,787 @@
1
+ """Reachy Mini app assistant functions."""
2
+
3
+ import json
4
+ import os
5
+ import subprocess
6
+ import sys
7
+ import tempfile
8
+ import time
9
+ from pathlib import Path
10
+ from typing import Any, Dict
11
+
12
+ import questionary
13
+ import toml
14
+ import yaml
15
+ from huggingface_hub import CommitOperationAdd, HfApi, get_repo_discussions, whoami
16
+ from jinja2 import Environment, FileSystemLoader
17
+ from rich.console import Console
18
+ from rich.progress import Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
19
+
20
+
21
+ def validate_app_name(text: str) -> bool | str:
22
+ """Validate the app name."""
23
+ if not text.strip():
24
+ return "App name cannot be empty."
25
+ if " " in text:
26
+ return "App name cannot contain spaces."
27
+ if "-" in text:
28
+ return "App name cannot contain dashes ('-'). Please use underscores ('_') instead."
29
+ if "/" in text or "\\" in text:
30
+ return "App name cannot contain slashes or backslashes ('/' or '\\')."
31
+ if "*" in text or "?" in text or "." in text:
32
+ return "App name cannot contain wildcard characters ('*', '?', or '.')."
33
+ return True
34
+
35
+
36
+ def is_git_repo(path: Path) -> bool:
37
+ """Check if the given path is inside a git repository."""
38
+ try:
39
+ subprocess.check_output(
40
+ ["git", "-C", path, "rev-parse", "--is-inside-work-tree"],
41
+ stderr=subprocess.STDOUT,
42
+ )
43
+ return True
44
+ except subprocess.CalledProcessError:
45
+ return False
46
+
47
+
48
+ def validate_location(text: str) -> bool | str:
49
+ """Validate the location where to create the app project."""
50
+ path = Path(text).expanduser().resolve()
51
+ if not os.path.exists(path):
52
+ return f"The path {path} does not exist."
53
+
54
+ return True
55
+
56
+
57
+ def validate_location_and_git_repo(text: str) -> bool | str:
58
+ """Validate the location where to create the app project, ensuring it's not in a git repo."""
59
+ path = Path(text).expanduser().resolve()
60
+ if not os.path.exists(path):
61
+ return f"The path {path} does not exist."
62
+ if is_git_repo(path):
63
+ return f"The path {path} is already inside a git repository."
64
+
65
+ return True
66
+
67
+
68
+ def create_cli(
69
+ console: Console, app_name: str | None, app_path: Path | None
70
+ ) -> tuple[str, str, Path]:
71
+ """Create a new Reachy Mini app project using a CLI."""
72
+ if app_name is None:
73
+ # 1) App name
74
+ console.print("$ What is the name of your app ?")
75
+ app_name = questionary.text(
76
+ ">",
77
+ default="",
78
+ validate=validate_app_name,
79
+ ).ask()
80
+
81
+ if app_name is None:
82
+ console.print("[red]Aborted.[/red]")
83
+ exit()
84
+ app_name = app_name.strip().lower()
85
+
86
+ # 2) Language
87
+ console.print("\n$ Choose the language of your app")
88
+ language = questionary.select(
89
+ ">",
90
+ choices=["python", "js"],
91
+ default="python",
92
+ ).ask()
93
+ if language is None:
94
+ console.print("[red]Aborted.[/red]")
95
+ exit()
96
+
97
+ # js is not supported yet
98
+ if language != "python":
99
+ console.print("[red]Currently only Python apps are supported. Aborted.[/red]")
100
+ exit()
101
+
102
+ if app_path is None:
103
+ # 3) App path
104
+ console.print("\n$ Where do you want to create your app project ?")
105
+ app_path = questionary.path(
106
+ ">",
107
+ default="",
108
+ validate=validate_location_and_git_repo,
109
+ ).ask()
110
+ if app_path is None:
111
+ console.print("[red]Aborted.[/red]")
112
+ exit()
113
+ app_path = Path(app_path).expanduser().resolve()
114
+ if is_git_repo(app_path):
115
+ console.print(
116
+ f"[red] The path {app_path} is already inside a git repository. "
117
+ "Please choose another path. Aborted.[/red]"
118
+ )
119
+ exit()
120
+
121
+ return app_name, language, app_path
122
+
123
+
124
+ def create(console: Console, app_name: str, app_path: Path) -> None:
125
+ """Create a new Reachy Mini app project with the given name at the specified path.
126
+
127
+ Args:
128
+ console (Console): The console object for printing messages.
129
+ app_name (str): The name of the app to create.
130
+ app_path (Path): The directory where the app project will be created.
131
+
132
+ """
133
+ app_name, language, app_path = create_cli(console, app_name, app_path)
134
+ app_name = app_name.replace(
135
+ "-", "_"
136
+ ) # Force underscores in app name (belt and suspenders)
137
+
138
+ TEMPLATE_DIR = Path(__file__).parent / "templates"
139
+ env = Environment(loader=FileSystemLoader(TEMPLATE_DIR))
140
+
141
+ def render_template(filename: str, context: Dict[str, str]) -> str:
142
+ template = env.get_template(filename)
143
+ return template.render(context)
144
+
145
+ base_path = Path(app_path).resolve() / app_name
146
+ if base_path.exists():
147
+ console.print(f"āŒ Folder {base_path} already exists.", style="bold red")
148
+ exit()
149
+
150
+ module_name = app_name
151
+ entrypoint_name = app_name.replace("-", "_")
152
+ class_name = "".join(word.capitalize() for word in module_name.split("_"))
153
+ class_name_display = " ".join(word.capitalize() for word in module_name.split("_"))
154
+
155
+ base_path.mkdir()
156
+ (base_path / module_name).mkdir()
157
+ (base_path / module_name / "static").mkdir()
158
+
159
+ # Generate files
160
+ context = {
161
+ "app_name": app_name,
162
+ "package_name": app_name,
163
+ "module_name": module_name,
164
+ "class_name": class_name,
165
+ "class_name_display": class_name_display,
166
+ "entrypoint_name": entrypoint_name,
167
+ }
168
+
169
+ (base_path / module_name / "__init__.py").touch()
170
+ (base_path / module_name / "main.py").write_text(
171
+ render_template("main.py.j2", context)
172
+ )
173
+ (base_path / module_name / "static" / "index.html").write_text(
174
+ render_template("static/index.html.j2", context)
175
+ )
176
+ (base_path / module_name / "static" / "style.css").write_text(
177
+ render_template("static/style.css.j2", context)
178
+ )
179
+ (base_path / module_name / "static" / "main.js").write_text(
180
+ render_template("static/main.js.j2", context)
181
+ )
182
+
183
+ (base_path / "pyproject.toml").write_text(
184
+ render_template("pyproject.toml.j2", context)
185
+ )
186
+ (base_path / "README.md").write_text(render_template("README.md.j2", context))
187
+
188
+ (base_path / "index.html").write_text(render_template("index.html.j2", context))
189
+ (base_path / "style.css").write_text(render_template("style.css.j2", context))
190
+ (base_path / ".gitignore").write_text(render_template("gitignore.j2", context))
191
+
192
+ # TODO assets dir with a .gif ?
193
+
194
+ console.print(f"āœ… Created app '{app_name}' in {base_path}/", style="bold green")
195
+
196
+
197
+ def install_app_with_progress(
198
+ console: Console, pip_executable: str, app_path: Path
199
+ ) -> None:
200
+ """Install the app in a temporary virtual environment with a progress spinner."""
201
+ console.print("Installing the app in the temporary virtual environment...")
202
+
203
+ # Start pip in the background, discard its output
204
+ process = subprocess.Popen(
205
+ [
206
+ pip_executable,
207
+ "install",
208
+ "-q", # quiet
209
+ str(app_path),
210
+ ],
211
+ stdout=subprocess.DEVNULL,
212
+ stderr=subprocess.STDOUT,
213
+ )
214
+
215
+ with Progress(
216
+ SpinnerColumn(),
217
+ TextColumn("[progress.description]{task.description}"),
218
+ TimeElapsedColumn(),
219
+ console=console,
220
+ ) as progress:
221
+ task_id = progress.add_task("Installing dependencies...", start=True)
222
+
223
+ # Keep the spinner running while pip is working
224
+ while process.poll() is None:
225
+ time.sleep(0.1)
226
+
227
+ # Mark task as finished
228
+ progress.update(task_id, description="Installation finished")
229
+
230
+ # Handle exit code like check=True would
231
+ if process.returncode != 0:
232
+ raise subprocess.CalledProcessError(process.returncode, process.args)
233
+
234
+
235
+ def check(console: Console, app_path: str) -> None:
236
+ """Check an existing Reachy Mini app project.
237
+
238
+ Args:
239
+ console (Console): The console object for printing messages.
240
+ app_path (str): Local path to the app to check.
241
+
242
+ """
243
+ if app_path is None:
244
+ console.print("\n$ What is the local path to the app you want to check?")
245
+ app_path = questionary.path(
246
+ ">",
247
+ default="",
248
+ validate=validate_location,
249
+ ).ask()
250
+ if app_path is None:
251
+ console.print("[red]Aborted.[/red]")
252
+ exit()
253
+ app_path = Path(app_path).expanduser().resolve()
254
+
255
+ if not os.path.exists(app_path):
256
+ console.print(f"[red]App path {app_path} does not exist.[/red]")
257
+ exit()
258
+
259
+ abs_app_path = Path(app_path).resolve()
260
+
261
+ # Check if there is a pyproject.toml file in the root of the app
262
+ pyproject_file = abs_app_path / "pyproject.toml"
263
+ if not pyproject_file.exists():
264
+ console.print("āŒ pyproject.toml is missing", style="bold red")
265
+ console.print(
266
+ "Make sure you are providing the path to the root of the app. This is the folder that contains pyproject.toml.",
267
+ style="bold blue",
268
+ )
269
+ sys.exit(1)
270
+
271
+ # Extract app name
272
+ with open(pyproject_file, "r", encoding="utf-8") as f:
273
+ pyproject_content = toml.load(f)
274
+ project = pyproject_content.get("project", {})
275
+ app_name = project.get("name", None)
276
+ if app_name is None:
277
+ console.print(
278
+ "āŒ Project name is missing in pyproject.toml", style="bold red"
279
+ )
280
+ sys.exit(1)
281
+
282
+ entrypoint_name = app_name
283
+ pkg_name = app_name.replace("-", "_")
284
+ class_name = "".join(word.capitalize() for word in pkg_name.split("_"))
285
+
286
+ console.print(f"\tExpected package name: {pkg_name}", style="dim")
287
+ console.print(f"\tExpected class name: {class_name}", style="dim")
288
+ console.print(f"\tExpected entrypoint name: {entrypoint_name}\n", style="dim")
289
+
290
+ # Check that:
291
+ # - index.html, style.css exist in the root of the app
292
+
293
+ if not os.path.exists(os.path.join(abs_app_path, "index.html")):
294
+ console.print("āŒ index.html is missing", style="bold red")
295
+ sys.exit(1)
296
+
297
+ if not os.path.exists(os.path.join(abs_app_path, "style.css")):
298
+ console.print("āŒ style.css is missing", style="bold red")
299
+ sys.exit(1)
300
+ console.print("āœ… index.html and style.css exist in the root of the app.")
301
+
302
+ # - pkg_name and pkg_name/__init__.py exists
303
+ if not os.path.exists(os.path.join(abs_app_path, pkg_name)) or not os.path.exists(
304
+ os.path.join(abs_app_path, pkg_name, "__init__.py")
305
+ ):
306
+ console.print(f"āŒ Package folder '{pkg_name}' is missing", style="bold red")
307
+ sys.exit(1)
308
+
309
+ if "entry-points" not in pyproject_content["project"]:
310
+ console.print(
311
+ "āŒ pyproject.toml is missing the entry-points section",
312
+ style="bold red",
313
+ )
314
+ sys.exit(1)
315
+
316
+ entry_points = pyproject_content["project"]["entry-points"]
317
+
318
+ if "reachy_mini_apps" not in entry_points:
319
+ console.print(
320
+ "āŒ pyproject.toml is missing the reachy_mini_apps entry-points section",
321
+ style="bold red",
322
+ )
323
+ sys.exit(1)
324
+
325
+ ep = entry_points["reachy_mini_apps"]
326
+ for k, v in ep.items():
327
+ console.print(f'Found entrypoint: {k} = "{v}"', style="dim")
328
+ if k == entrypoint_name and v == f"{pkg_name}.main:{class_name}":
329
+ console.print(
330
+ "āœ… pyproject.toml contains the correct entrypoint for the app."
331
+ )
332
+ break
333
+ else:
334
+ console.print(
335
+ f'āŒ pyproject.toml is missing the entrypoint for the app: {entrypoint_name} = "{pkg_name}.main:{class_name}"',
336
+ style="bold red",
337
+ )
338
+ sys.exit(1)
339
+
340
+ # - <app_name>/__init__.py exists
341
+ pkg_path = Path(abs_app_path) / pkg_name
342
+ init_file = pkg_path / "__init__.py"
343
+
344
+ if not init_file.exists():
345
+ console.print("āŒ __init__.py is missing", style="bold red")
346
+ sys.exit(1)
347
+
348
+ console.print(f"āœ… {app_name}/__init__.py exists.")
349
+
350
+ main_file = pkg_path / "main.py"
351
+ if not main_file.exists():
352
+ console.print("āŒ main.py is missing", style="bold red")
353
+ sys.exit(1)
354
+ console.print(f"āœ… {app_name}/main.py exists.")
355
+
356
+ # - <app_name>/main.py contains a class named <AppName> that inherits from ReachyMiniApp
357
+ with open(main_file, "r") as f:
358
+ main_content = f.read()
359
+ class_name = "".join(
360
+ word.capitalize() for word in app_name.replace("-", "_").split("_")
361
+ )
362
+ if f"class {class_name}(ReachyMiniApp)" not in str(main_content):
363
+ console.print(
364
+ f"āŒ main.py is missing the class {class_name} that inherits from ReachyMiniApp",
365
+ style="bold red",
366
+ )
367
+ sys.exit(1)
368
+ console.print(
369
+ f"āœ… main.py contains the class {class_name} that inherits from ReachyMiniApp."
370
+ )
371
+
372
+ # - README.md exists in the root of the app
373
+ if not os.path.exists(os.path.join(abs_app_path, "README.md")):
374
+ console.print("āŒ README.md is missing", style="bold red")
375
+ sys.exit(1)
376
+ console.print("āœ… README.md exists in the root of the app.")
377
+
378
+ def parse_readme(file_path: str) -> Any:
379
+ """Parse the metadata section of the README.md file."""
380
+ with open(file_path, "r") as f:
381
+ lines = f.readlines()
382
+
383
+ in_metadata = False
384
+ metadata = ""
385
+ for line in lines:
386
+ line = line.strip()
387
+ if line == "---":
388
+ if not in_metadata:
389
+ in_metadata = True
390
+ else:
391
+ break
392
+ elif in_metadata:
393
+ metadata += line + "\n"
394
+
395
+ try:
396
+ metadata = yaml.safe_load(metadata)
397
+ except yaml.YAMLError as e:
398
+ console.print(f"āŒ Error parsing YAML metadata: {e}", style="bold red")
399
+ sys.exit(1)
400
+
401
+ return metadata
402
+
403
+ # - README.md contains at least a title and the tags "reachy_mini" and "reachy_mini_{python/js}_app"
404
+ readme_metadata = parse_readme(os.path.join(abs_app_path, "README.md"))
405
+ if len(readme_metadata) == 0:
406
+ console.print("āŒ README.md is missing metadata section.", style="bold red")
407
+ sys.exit(1)
408
+ if "title" not in readme_metadata.keys():
409
+ console.print(
410
+ "āŒ README.md is missing the title key in metadata.", style="bold red"
411
+ )
412
+ sys.exit(1)
413
+ if readme_metadata["title"] == "":
414
+ console.print("āŒ README.md title cannot be empty.", style="bold red")
415
+ sys.exit(1)
416
+
417
+ if "tags" not in readme_metadata.keys():
418
+ console.print(
419
+ "āŒ README.md is missing the tags key in metadata.", style="bold red"
420
+ )
421
+ sys.exit(1)
422
+
423
+ if "reachy_mini" not in readme_metadata["tags"]:
424
+ console.print(
425
+ 'āŒ README.md must contain the "reachy_mini" tag', style="bold red"
426
+ )
427
+ sys.exit(1)
428
+
429
+ if (
430
+ "reachy_mini_python_app" not in readme_metadata["tags"]
431
+ and "reachy_mini_js_app" not in readme_metadata["tags"]
432
+ ):
433
+ console.print(
434
+ 'āŒ README.md must contain either the "reachy_mini_python_app" or "reachy_mini_js_app" tag',
435
+ style="bold red",
436
+ )
437
+ sys.exit(1)
438
+
439
+ console.print("āœ… README.md contains the required metadata.")
440
+ # - <app_name>/main.py exists
441
+
442
+ # Now, create a temporary python venv in a temp dir, `pip install . the app, check that it works and that the entrypoint is registered
443
+ with tempfile.TemporaryDirectory() as tmpdir:
444
+ # change dir to tmpdir
445
+ os.chdir(tmpdir)
446
+
447
+ console.print(
448
+ f"\nCreating a temporary virtual environment to test the app... (tmp dir: {tmpdir})"
449
+ )
450
+ venv_path = os.path.join(tmpdir, "venv")
451
+ subprocess.run([sys.executable, "-m", "venv", venv_path], check=True)
452
+
453
+ pip_executable = os.path.join(
454
+ venv_path,
455
+ "Scripts" if os.name == "nt" else "bin",
456
+ "pip",
457
+ )
458
+ python_executable = os.path.join(
459
+ venv_path,
460
+ "Scripts" if os.name == "nt" else "bin",
461
+ "python",
462
+ )
463
+
464
+ install_app_with_progress(console, pip_executable, abs_app_path)
465
+
466
+ console.print("Checking that the app entrypoint is registered...")
467
+
468
+ # use from importlib.metadata import entry_points
469
+
470
+ check_script = (
471
+ f"from importlib.metadata import entry_points; "
472
+ f"eps = entry_points(group='reachy_mini_apps'); "
473
+ f"app_names = [ep.name for ep in eps]; "
474
+ f"import sys; "
475
+ f"sys.exit(0) if '{app_name}' in app_names else sys.exit(1)"
476
+ )
477
+ if (
478
+ subprocess.run(
479
+ [python_executable, "-c", check_script],
480
+ # capture_output=True,
481
+ text=True,
482
+ ).returncode
483
+ != 0
484
+ ):
485
+ console.print(
486
+ f"āŒ App '{app_name}' entrypoint is not registered correctly.",
487
+ style="bold red",
488
+ )
489
+ sys.exit(1)
490
+ console.print("āœ… App entrypoint is registered correctly.")
491
+
492
+ # Now try to uninstall the app and check that it uninstalls correctly
493
+ console.print("Uninstalling the app from the temporary virtual environment...")
494
+ subprocess.run(
495
+ [pip_executable, "uninstall", "-y", app_name],
496
+ check=True,
497
+ )
498
+
499
+ if (
500
+ subprocess.run(
501
+ [python_executable, "-c", check_script],
502
+ capture_output=True,
503
+ text=True,
504
+ ).returncode
505
+ == 0
506
+ ):
507
+ console.print(
508
+ f"āŒ App '{app_name}' was not uninstalled correctly.",
509
+ style="bold red",
510
+ )
511
+ sys.exit(1)
512
+
513
+ console.print("āœ… App installation and uninstallation tests passed.")
514
+
515
+ console.print(f"\nāœ… App '{app_name}' passed all checks!", style="bold green")
516
+
517
+
518
+ def request_app_addition(new_app_repo_id: str) -> bool:
519
+ """Request to add the new app to the official Reachy Mini app store."""
520
+ api = HfApi()
521
+
522
+ repo_id = "pollen-robotics/reachy-mini-official-app-store"
523
+ file_path = "app-list.json"
524
+
525
+ # 0. Detect current HF user
526
+ user = whoami()["name"]
527
+
528
+ # 1. Check if there is already an open PR by this user for this app
529
+ # (we used commit_message=f"Add {new_app_repo_id} to app-list.json",
530
+ # which becomes the PR title)
531
+ existing_prs = get_repo_discussions(
532
+ repo_id=repo_id,
533
+ repo_type="dataset",
534
+ author=user,
535
+ discussion_type="pull_request",
536
+ discussion_status="open",
537
+ )
538
+
539
+ for pr in existing_prs:
540
+ if new_app_repo_id in pr.title:
541
+ print(
542
+ f"An open PR already exists for {new_app_repo_id} by {user}: "
543
+ f"https://huggingface.co/{repo_id}/discussions/{pr.num}"
544
+ )
545
+ return False
546
+
547
+ # 2. Download current file from the dataset repo
548
+ local_downloaded = api.hf_hub_download(
549
+ repo_id=repo_id,
550
+ filename=file_path,
551
+ repo_type="dataset",
552
+ )
553
+
554
+ with open(local_downloaded, "r") as f:
555
+ app_list = json.load(f)
556
+
557
+ # 3. Modify JSON (append if not already present)
558
+ if new_app_repo_id not in app_list:
559
+ app_list.append(new_app_repo_id)
560
+ else:
561
+ print(f"{new_app_repo_id} is already in the app list.")
562
+ # You might still want to continue and create the PR, or early-return here.
563
+ return False
564
+
565
+ # 4. Save updated JSON to a temporary path
566
+ with tempfile.TemporaryDirectory() as tmpdir:
567
+ updated_path = os.path.join(tmpdir, file_path)
568
+ os.makedirs(os.path.dirname(updated_path), exist_ok=True)
569
+ with open(updated_path, "w") as f:
570
+ json.dump(app_list, f, indent=4)
571
+ f.write("\n")
572
+
573
+ # 5. Commit with create_pr=True
574
+ commit_info = api.create_commit(
575
+ repo_id=repo_id,
576
+ repo_type="dataset",
577
+ commit_message=f"Add {new_app_repo_id} to app-list.json",
578
+ commit_description=(
579
+ f"Append `{new_app_repo_id}` to the list of Reachy Mini apps."
580
+ ),
581
+ operations=[
582
+ CommitOperationAdd(
583
+ path_in_repo=file_path,
584
+ path_or_fileobj=updated_path,
585
+ )
586
+ ],
587
+ create_pr=True,
588
+ )
589
+
590
+ print("Commit URL:", commit_info.commit_url)
591
+ print("PR URL:", commit_info.pr_url) # None if no PR was opened
592
+ return True
593
+
594
+
595
+ def try_to_push(console: Console, _app_path: Path) -> bool:
596
+ """Try to push changes to the remote repository."""
597
+ console.print("Pushing changes to the remote repository ...", style="bold blue")
598
+ push_result = subprocess.run(
599
+ f"cd {_app_path} && git push",
600
+ shell=True,
601
+ capture_output=True,
602
+ text=True,
603
+ )
604
+ if push_result.returncode != 0:
605
+ console.print(
606
+ f"[red]Failed to push changes to the remote repository: {push_result.stderr}[/red]"
607
+ )
608
+ return False
609
+ return True
610
+
611
+
612
+ def publish(
613
+ console: Console,
614
+ app_path: str,
615
+ commit_message: str,
616
+ official: bool = False,
617
+ no_check: bool = False,
618
+ ) -> None:
619
+ """Publish the app to the Reachy Mini app store.
620
+
621
+ Args:
622
+ console (Console): The console object for printing messages.
623
+ app_path (str): Local path to the app to publish.
624
+ commit_message (str): Commit message for the app publish.
625
+ official (bool): Request to publish the app as an official Reachy Mini app.
626
+ no_check (bool): Don't run checks before publishing the app.
627
+
628
+ """
629
+ import huggingface_hub as hf
630
+
631
+ if app_path is None:
632
+ console.print("\n$ What is the local path to the app you want to publish?")
633
+ app_path = questionary.path(
634
+ ">",
635
+ default="",
636
+ validate=validate_location,
637
+ ).ask()
638
+ if app_path is None:
639
+ console.print("[red]Aborted.[/red]")
640
+ exit()
641
+ name_of_repo = Path(app_path).name
642
+ if name_of_repo == "reachy_mini":
643
+ console.print(
644
+ "[red] Safeguard : You may have selected reachy_mini repo as your app. Aborted.[/red]"
645
+ )
646
+ exit()
647
+ app_path = Path(app_path).expanduser().resolve() # type: ignore
648
+ if not os.path.exists(app_path):
649
+ console.print(f"[red]App path {app_path} does not exist.[/red]")
650
+ sys.exit()
651
+
652
+ if not hf.get_token():
653
+ console.print(
654
+ "[red]You need to be logged in to Hugging Face to publish an app.[/red]"
655
+ )
656
+ # Do you want to login now (will run hf auth login)
657
+ if questionary.confirm("Do you want to login now?").ask():
658
+ console.print("Generate a token at https://huggingface.co/settings/tokens")
659
+ hf.login()
660
+ else:
661
+ console.print("[red]Aborted.[/red]")
662
+ exit()
663
+
664
+ username = hf.whoami()["name"]
665
+ repo_path = f"{username}/{Path(app_path).name}"
666
+ repo_url = f"https://huggingface.co/spaces/{repo_path}"
667
+
668
+ if hf.repo_exists(repo_path, repo_type="space"):
669
+ if official:
670
+ # ask for confirmation
671
+ if not questionary.confirm(
672
+ "Are you sure you want to ask to publish this app as an official Reachy Mini app?"
673
+ ).ask():
674
+ console.print("[red]Aborted.[/red]")
675
+ exit()
676
+
677
+ worked = request_app_addition(repo_path)
678
+ if worked:
679
+ console.print(
680
+ "\nYou have requested to publish your app as an official Reachy Mini app."
681
+ )
682
+ console.print(
683
+ "The Pollen and Hugging Face teams will review your app. Thank you for your contribution!"
684
+ )
685
+ exit()
686
+
687
+ console.print("App already exists on Hugging Face Spaces.", style="bold blue")
688
+ os.system(f"cd {app_path} && git pull {repo_url} main")
689
+
690
+ status_output = (
691
+ subprocess.check_output(
692
+ f"cd {app_path} && git status --porcelain", shell=True
693
+ )
694
+ .decode("utf-8")
695
+ .strip()
696
+ )
697
+
698
+ if status_output == "":
699
+ console.print(
700
+ "āœ… No changes to commit.",
701
+ style="bold green",
702
+ )
703
+ push_anyway = questionary.confirm(
704
+ "Do you want to try to push anyway?"
705
+ ).ask()
706
+ if not push_anyway:
707
+ console.print("[red]Aborted.[/red]")
708
+ exit()
709
+ else:
710
+ console.print("Trying to push anyway...")
711
+ pushed = try_to_push(console, Path(app_path))
712
+ exit()
713
+
714
+ if no_check:
715
+ console.print(
716
+ "āš ļø Skipping checks as per --nocheck flag.",
717
+ style="bold yellow",
718
+ )
719
+ else:
720
+ console.print(f"\nšŸ”Ž Running checks on the app at {app_path}/...")
721
+ check(console, str(app_path))
722
+
723
+ commit_message = questionary.text(
724
+ "\n$ Enter a commit message for the update:",
725
+ default="Update app",
726
+ ).ask()
727
+ if commit_message is None:
728
+ console.print("[red]Aborted.[/red]")
729
+ exit()
730
+
731
+ # commit local changes
732
+ console.print("Committing changes locally ...", style="bold blue")
733
+ os.system(f"cd {app_path} && git add . && git commit -m '{commit_message}'")
734
+
735
+ # && git push HEAD:main"
736
+
737
+ pushed = try_to_push(console, Path(app_path))
738
+ if not pushed:
739
+ exit()
740
+
741
+ console.print("āœ… App updated successfully.")
742
+ else:
743
+ if no_check:
744
+ console.print(
745
+ "āš ļø Skipping checks as per --nocheck flag.",
746
+ style="bold yellow",
747
+ )
748
+ else:
749
+ console.print(f"\nšŸ”Ž Running checks on the app at {app_path}/...")
750
+ check(console, str(app_path))
751
+
752
+ console.print("Do you want your space to be created private or public?")
753
+ privacy = questionary.select(
754
+ ">",
755
+ choices=["private", "public"],
756
+ default="public",
757
+ ).ask()
758
+
759
+ hf.create_repo(
760
+ repo_path,
761
+ repo_type="space",
762
+ private=(privacy == "private"),
763
+ exist_ok=False,
764
+ space_sdk="static",
765
+ )
766
+ os.system(
767
+ f"cd {app_path} && git init && git remote add space {repo_url} && git add . && git commit -m 'Initial commit' && git push --set-upstream -f space HEAD:main"
768
+ )
769
+
770
+ console.print("āœ… App published successfully.", style="bold green")
771
+
772
+ if official:
773
+ # ask for confirmation
774
+ if not questionary.confirm(
775
+ "Are you sure you want to ask to publish this app as an official Reachy Mini app?"
776
+ ).ask():
777
+ console.print("[red]Aborted.[/red]")
778
+ exit()
779
+
780
+ worked = request_app_addition(repo_path)
781
+ if worked:
782
+ console.print(
783
+ "\nYou have requested to publish your app as an official Reachy Mini app."
784
+ )
785
+ console.print(
786
+ "The Pollen and Hugging Face teams will review your app. Thank you for your contribution!"
787
+ )