Running a Python FastAPI (Uvicorn) service from .NET Aspire

NET Aspire isn’t limited to .NET services. You can orchestrate a Python service (FastAPI on Uvicorn) right alongside your .NET components—same lifecycle, unified logs, single dotnet run.

Below is a minimal setup that boots a FastAPI app with health endpoint, exposes it via Aspire, and keeps everything tidy in one solution.

Folder layout

04_PythonUvicorn/
├─ AppHost.cs
├─ PythonUvicorn.csproj
├─ appsettings.json
├─ appsettings.Development.json
├─ README.md
└─ uvicornapp-api/          # Python app lives here
   ├─ main.py
   ├─ requirements.txt
   └─ (optional) .venv/

AppHost.cs (Aspire)

var builder = DistributedApplication.CreateBuilder(args);

var uvicorn = builder.AddUvicornApp(
        name: "uvicornapp",
        projectDirectory: "./uvicornapp-api",
        appName: "main:app"
    )
    .WithHttpEndpoint(targetPort: 8000)   // app listens on 8000
    .WithExternalHttpEndpoints();         // optional, expose to host

builder. Build().Run();

What this does

  • AddUvicornApp registers a Python app that Aspire will run with uvicorn.
  • projectDirectory points at your Python folder (where main.py and requirements.txt live).
  • appName: "main:app" tells Uvicorn to load the app object from main.py.
  • .WithHttpEndpoint(targetPort: 8000) documents the port your app listens on.
  • .WithExternalHttpEndpoints() exposes the service so you can open it from the Aspire dashboard.

The Python service (FastAPI)

uvicornapp-api/main.py

from fastapi import FastAPI

app = FastAPI()

@app.get("/health")
def health():
    return {"status": "ok"}

@app.get("/")
def root():
    return {"hello": "aspire + uvicorn"}

uvicornapp-api/requirements.txt

fastapi
uvicorn[standard]

Creating the Python app (venv + deps)

From 04_PythonUvicorn/uvicornapp-api:

macOS/Linux

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
deactivate

Windows (PowerShell)

py -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
deactivate

Aspire doesn’t need the venv to be active when you run the AppHost, but having a local .venv/ helps keep dependencies self-contained. If you prefer, you can bake the venv activation into your Uvicorn command or use a global Python—your choice.

Run everything

From 04_PythonUvicorn:

dotnet run

Open the Aspire dashboard, find the uvicornapp service, and click through to its URL. You should see:

  • GET /{"hello":"aspire + uvicorn"}
  • GET /health{"status":"ok"}

Local development tips

  • Health checks: You can point Aspire liveness/readiness to /health if you add health probes later.
  • Logs: Aspire captures Uvicorn logs so you can troubleshoot from one place.
  • Cross-service calls: If a .NET API needs to call this Python service, use Aspire service discovery (or read the bound URL from configuration) rather than hardcoding ports.

[Source code]

That’s all folks!

Cheers!
Gašper Rupnik

{End.}

Leave a comment

Website Powered by WordPress.com.

Up ↑