Skip to main content

FoxyGPU

Tests

Run local code — FastAPI backends, frontend dev servers, or anything else — on Google Colab's free-tier GPU, driven entirely from your own machine.

How it works

foxygpu launch opens FoxyGPU's own runner notebook directly in Colab — no manual notebook upload, and no GitHub account or token needed. The notebook is identical for every user (nothing personalized is baked in), so it's just committed straight into this repo and Colab loads it from there; Colab can open any public GitHub file with zero authentication. That notebook starts a control-plane agent, reached from your machine over a Cloudflare Tunnel quick tunnel (no account needed). The local foxygpu CLI talks to that agent to upload your project, start it with a shell command, stream its logs, and expose whatever port it's listening on with its own public URL.

 local machine                              Google Colab VM (GPU runtime)
┌─────────────────┐   HTTPS/WSS via         ┌─────────────────────────────┐
│  foxygpu CLI     │◄──cloudflared tunnel──►│  foxygpu_agent (FastAPI)     │
└─────────────────┘                         │  spawns your process         │
                                              │  (uvicorn / npm / anything)  │
                                              └─────────────────────────────┘

Every agent endpoint requires a bearer token generated at startup — the tunnel URL alone isn't enough to run anything on your VM.

Install

Everything — the CLI and the Colab agent it deploys — ships as one Python package:

pip install -e .

Setup

1. Launch the Colab runtime

foxygpu launch

This just opens Colab straight to FoxyGPU's own committed notebook — nothing to sign in to, no token, no account needed.

In the browser: select a GPU runtime (Runtime > Change runtime type > GPU), run all cells. The last cell prints a foxygpu connect ... command — copy it.

Prefer not to open a link we host at all? foxygpu notebook ./FoxyGPU_Runner.ipynb writes the same notebook to a local file so you can read it yourself and upload it to Colab manually (File > Upload notebook) — zero network calls to anything but Colab itself.

If you've modified foxygpu/agent_source.py locally and want the one-click experience for your own version without forking/hosting a repo, foxygpu launch --gist publishes your copy to a GitHub Gist instead — that path does need a classic GitHub token with the gist scope (fine-grained tokens don't support the Gists API and fail with a 404); create one at https://github.com/settings/tokens -> "Generate new token (classic)".

2. Connect

Paste the command Colab printed, e.g.:

foxygpu connect https://xxxx.trycloudflare.com --token <token>

Usage

Run a project (any language/framework — it's just a shell command). The agent picks a free port for you and injects it as $PORT — reference that instead of a literal number so you never have to think about which ports are free or reserved:

foxygpu run ./my-fastapi-app --cmd 'pip install -r requirements.txt && uvicorn main:app --host 0.0.0.0 --port $PORT' --expose

Shell note: use single quotes around the --cmd value, exactly as above, in PowerShell, bash, or zsh — all three treat single quotes as a literal string, so $PORT and && reach the remote command unchanged. This does not work in cmd.exe (no concept of single-quoted literal strings, and it interprets && itself) — use PowerShell or a bash-like shell instead.

Logs stream live, and the CLI prints which port got assigned. --expose immediately opens a public tunnel once the process starts and prints the URL. If you skip it, expose later — with no argument it defaults to the most recently started process's port:

foxygpu expose

Edited your code and want to update what's running? foxygpu run always starts a fresh, separate deployment — it won't stop whatever's already running first. Use redeploy instead, which stops the previous deployment of the same project (matched by directory name, or --name if you gave one) before starting the new one:

foxygpu redeploy ./my-fastapi-app --cmd 'pip install -r requirements.txt && uvicorn main:app --host 0.0.0.0 --port $PORT' --expose

If the new run lands back on the same port — likely, since stopping the old one just freed it — an existing exposed URL for that port keeps working automatically, no need to expose again.

Check GPU status and running processes (including their assigned ports):

foxygpu status

Stream logs for a process, reconnect after detaching, or stop it (add --all to stop everything):

foxygpu logs <process-id>
foxygpu stop <process-id>
foxygpu stop --all

Pressing Ctrl+C while logs are streaming only detaches your terminal — the remote process keeps running on Colab. The CLI reminds you of the logs/stop commands above when you do this.

More examples

Node.js app (read process.env.PORT in your server code):

foxygpu run ./my-node-app --cmd 'npm install && node server.js' --expose

Frontend dev server (Vite/React/etc.):

foxygpu run ./my-frontend --cmd 'npm install && npm run dev -- --host 0.0.0.0 --port $PORT' --expose

One-off script or training job (no server, so skip --expose):

foxygpu run ./train-job --cmd 'pip install -r requirements.txt && python train.py'

See foxygpu run --help for this same set of examples from the CLI.

Full working example

examples/ollama-chat is a complete ChatGPT-style app (FastAPI backend + a small frontend) that runs a real GPU-backed Ollama model on Colab — a good first thing to deploy to confirm your setup end-to-end.

Excluding files from upload

By default .git, node_modules, __pycache__, venv/.venv, and a few build directories are excluded when zipping your project. Add more patterns by copying .foxygpuignore.default to .foxygpuignore in your project root.

Development

The test suite runs a real instance of the agent locally (no Colab needed) and drives it over HTTP/WebSocket, plus in-process CLI tests via Typer's test runner. It never touches your real ~/.foxygpu/config.json — every test gets an isolated one automatically.

pip install -e ".[dev]"
pytest

Known limitations

  • FastAPI is only used to build the agent itself (the control-plane server running inside Colab) — it is not a requirement for what you deploy. foxygpu run just executes whatever shell command you give it via --cmd, so any language or framework the Colab VM can run works (Node, Go, Rust, Flask, Streamlit, a plain training script, anything), not just Python or FastAPI.
  • Colab free-tier sessions are ephemeral (idle timeout, ~12h cap). If the session restarts, run the notebook again (re-run foxygpu launch if you closed the tab) and foxygpu connect again with the new URL/token.
  • The control URL and token grant code execution on the VM — don't share them.
  • foxygpu launch --gist (the opt-in path) publishes to a public Gist (Gist API has no private-but-linkable option) — it contains no secrets (the agent's token is generated fresh at runtime in Colab, not baked into the notebook), but anyone who finds the Gist URL can see and re-run it against their own Colab.
  • The agent source lives at foxygpu/agent_source.py. The committed notebook/FoxyGPU_Runner.ipynb embeds a copy of it — regenerate that file with foxygpu notebook notebook/FoxyGPU_Runner.ipynb and commit it after changing the agent, since (unlike --gist, which always embeds the current source) the default launch opens the version already committed to this repo.
  • Port 8765 is reserved — the agent itself listens there inside Colab. You shouldn't need to think about this: reference $PORT in your --cmd (see Usage) and the agent hands you a free port automatically, preferring 9876 and falling back to another free one if that's taken (e.g. a second concurrent project).
  • A command with an animated progress bar can hang your whole --cmd chain forever. Some CLI tools (Ollama's pull is one — see examples/ollama-chat) never exit their progress renderer when run through a non-interactive pipe like the one the agent uses to capture output, even though the real work finishes. Since foxygpu run chains commands with &&, a hung one blocks everything after it. If a step seems stuck, check whether it actually finished (e.g. via a second foxygpu run with a quick status-checking command) before assuming it's slow — the fix is usually prefixing that one command with TERM=dumb.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

foxygpu-0.1.0.tar.gz (26.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

foxygpu-0.1.0-py3-none-any.whl (20.7 kB view details)

Uploaded Python 3

File details

Details for the file foxygpu-0.1.0.tar.gz.

File metadata

  • Download URL: foxygpu-0.1.0.tar.gz
  • Upload date:
  • Size: 26.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.9

File hashes

Hashes for foxygpu-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8bfc3f3c0188fdff229ebd69e0cff95bd26550f56528330b2b96b8e8837c4fb4
MD5 534718068ae1d0de1c56065a82be3185
BLAKE2b-256 8c3d6705e82e966f9e837629c3dd4e17e14a05ead5315efb9fba34bf2a0a75f3

See more details on using hashes here.

File details

Details for the file foxygpu-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: foxygpu-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.9

File hashes

Hashes for foxygpu-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 406da23e32646a860ca65308a9356f1b4165db5899cadb9caa662d80a254449c
MD5 a6fbdca54f912197406c32df4784cf49
BLAKE2b-256 fe6a80a71a9804837ca6ba30161625719fb9f3f7d95964d834f4d0ec9704a171

See more details on using hashes here.

Release history Release notifications | RSS feed

0.2.1

2 files

0.2.0

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page