Publishing to HuggingFace: A Different Paradigm
Refactored Focus Guardian for the Pollen Robotics ecosystem. Learned the hard way that dashboard plugins work differently than standalone apps.
Getting Focus Guardian into the HuggingFace/Pollen Robotics ecosystem required more than just uploading code. The entire architecture had to change.
Two Different Paradigms
What we built (standalone):
``python
def main():
robot = get_robot() # We manage connection
demo = create_gradio_app()
demo.launch() # We control lifecycle
``
What Pollen expects (dashboard plugin):
``python
class FocusGuardian(ReachyMiniApp):
def run(self, reachy_mini, stop_event):
# Robot already connected by daemon
# Dashboard controls start/stop
while not stop_event.is_set():
# Do stuff with reachy_mini
``
The key insight: apps in the Reachy Mini ecosystem are plugins, not standalone applications.
The Refactor
Created new package structure with pyproject.toml, moved to ReachyMiniApp inheritance, added stop_event handling for clean shutdown.
The Publishing Moment
pythonfrom huggingface_hub import HfApi
api = HfApi()
api.upload_folder(
folder_path="./focus-guardian-hf",
repo_id="RyeCatcher/focus-guardian",
repo_type="space"
)Result: https://huggingface.co/spaces/RyeCatcher/focus-guardian
Plot Twist: It's a Static Site
First deploy failed with ModuleNotFoundError: No module named 'reachy_mini'. Of course — the SDK runs locally where the robot is, not on HF servers!
Fixed by changing sdk: gradio to sdk: static. The Space is a *distribution point* (landing page + pip install source), not a running app.
Lesson Learned
HuggingFace Spaces for Reachy Mini apps serve two purposes: (1) discovery/landing page, (2) pip-installable package. The actual app runs locally.