Skip to main content
ngrok-fastapi opens an ngrok endpoint to a FastAPI app with one call:
The package is built on the Python SDK. attach() wraps your app’s lifespan, so the endpoint opens when the app starts and closes when it stops. If you already pass a lifespan= to FastAPI(), attach() composes with it rather than replacing it.
ngrok-fastapi is published on PyPI at version 0.1.0 and maintained in the ngrok-samples/ngrok-fastapi repository.

What you’ll need

1. Install the package

The package depends on fastapi and the ngrok Python SDK, so pip installs those too. You need an ASGI server such as uvicorn to run the app.

2. Set your auth token

Export your auth token as an environment variable:
The package reads NGROK_AUTHTOKEN from the environment when the app starts.

3. Attach ngrok to your app

Call attach() right after you create the app, with the port your ASGI server listens on:
main.py
The port in Config must match the port your server binds, because the endpoint forwards to localhost:<port>. It defaults to 8000.

4. Test your endpoint

Run your app:
The package prints Ingress established at: followed by the public URL. With no url in Config, that URL is your account’s dev domain. Open it in your browser to see your FastAPI app.

Configuration

Pass a Config to set the URL, add a Traffic Policy, or change the binding:

Multiple endpoints

attach_many() opens one endpoint per Config, on a single session, and ties all of them to the same app’s lifespan:
attach() is the one-endpoint case of attach_many(). Each Config can point at a different local port, so one FastAPI app can front other services running on the same machine. Every endpoint needs its own url, or pooling=True on each endpoint that shares one. If two endpoints would share a URL without pooling, including two endpoints that both leave url unset and land on your dev domain, the package raises ngrok_fastapi.CollisionError during startup before opening a session. Without that check, ngrok lets the most recently opened listener win and the other goes unreachable with no error.

Limits and availability

  • The package opens HTTP endpoints only. For TCP or TLS endpoints, use the Python SDK directly.
  • The endpoint opens during lifespan startup, so your ASGI server must run lifespan events. uvicorn does by default.
  • An INTERNAL binding requires a url that ends in .internal. ngrok rejects any other URL with ERR_NGROK_9029.
  • A URL that another agent or a Cloud Endpoint already claims fails with ERR_NGROK_334.
  • Endpoint counts and domains follow your plan’s limits. See free plan limits.

What’s next?