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?