Time: ~50 minutes of coding. You won't finish everything — that's expected.
Language: Python 3.9+. AI assistants / autocomplete: <ALLOWED / NOT ALLOWED — interviewer will confirm>.
SDK docs: https://github.com/runloopai/api-client-python (see api.md and README.md)
At Runloop, customers constantly need to run the same command across a fleet of devboxes — think "run this test suite on 20 fresh sandboxes" or "check the installed CUDA version everywhere." You're going to build the small CLI tool that does this.
Build rlfan:
python fanout.py --count 5 --command "python --version" [--timeout 60] [--mock]
- Provision
--countdevboxes and wait until each is running. - Execute
--commandon all of them concurrently — total wall-clock time should be roughly the time of the slowest box, not the sum. - Collect results and print a summary at the end: per-devbox ID, exit status,
duration, and the first line of stdout/stderr. The process exit code should be
0only if every command succeeded. - Tear down cleanly. No devbox should be left running when the tool exits — including when provisioning fails partway through, a command errors, or the run times out. (Leaked devboxes cost customers money. We check.)
- One box failing must not prevent results from the others, and must not prevent any box from being shut down.
--timeoutbounds the whole run. On timeout, report what you have and clean up.
--retries N: retry a failed provision or command on a fresh devbox.--max-concurrent N: cap in-flight provisioning (the API rate-limits).- Stream results as they complete instead of only at the end.
- Structured
--output jsonmode suitable for piping into other tools.
starter/fanout.py— CLI skeleton, client setup, and a working single-devbox example (run_one) showing the exact SDK calls you need. Start by reading it.starter/mock_runloop.py— a drop-in fake client (--mockflag) with simulated latency and injectable failures, so you can develop and test without touching the network.RLFAN_MOCK_FAIL_RATE=0.3makes ~30% of operations fail — use it to exercise your error paths. Runs against the real API too ifRUNLOOP_API_KEYis set and you drop--mock.
Working code first; polish later. We care about correct concurrency, honest error handling, and guaranteed cleanup far more than clever abstractions. Talk through your tradeoffs as you go — sync threads vs. asyncio, where retries belong, what "clean teardown" means when the process is killed. It's fine (encouraged) to ask questions; the spec is intentionally a little underspecified.