Python integration
Dette indhold er ikke tilgængeligt i dit sprog endnu.
The Aspire Python hosting integration lets you model Python scripts, modules, executables, and ASGI web apps as first-class resources in your AppHost project. Aspire manages virtual environment setup, injects connection strings and service URLs into the Python process, and wires up service discovery and observability automatically.
Hosting integration
Section titled “Hosting integration”aspire add pythonAspire CLI er interaktiv; vælg det passende søgeresultat når du bliver spurgt:
Select an integration to add:
> python (Aspire.Hosting.Python)> Other results listed as selectable options...#:package Aspire.Hosting.Python@*<PackageReference Include="Aspire.Hosting.Python" Version="*" />Add Python app
Section titled “Add Python app”Use AddPythonApp to run a Python script directly:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddPythonApp( name: "python-api", projectDirectory: "../python-app", scriptPath: "main.py") .WithHttpEndpoint(port: 8000, env: "PORT");
builder.AddProject<Projects.ExampleProject>("example") .WithReference(python);
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addPythonApp("python-api", "../python-app", "main.py");await python.withHttpEndpoint({ port: 8000, env: "PORT" });
const example = await builder.addProject("example", "../ExampleProject/ExampleProject.csproj");await example.withReference(python);
await builder.build().run();AddPythonApp / addPythonApp requires:
- name — the resource name shown in the Aspire dashboard
- projectDirectory / appDirectory — path to the directory containing your Python application
- scriptPath — the Python script to run, relative to the project directory
Add Python module
Section titled “Add Python module”Use AddPythonModule to run a Python module (the equivalent of python -m <module>):
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddPythonModule( name: "python-module", projectDirectory: "../python-app", moduleName: "mymodule") .WithHttpEndpoint(port: 8000, env: "PORT");
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addPythonModule("python-module", "../python-app", "mymodule");await python.withHttpEndpoint({ port: 8000, env: "PORT" });
await builder.build().run();AddPythonModule / addPythonModule requires:
- name — the resource name shown in the Aspire dashboard
- projectDirectory / appDirectory — path to the directory containing your Python application
- moduleName — the Python module to run
Add Python executable
Section titled “Add Python executable”Use AddPythonExecutable to run a CLI tool installed in the virtual environment (for example, uvicorn or a custom script):
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddPythonExecutable( name: "python-tool", projectDirectory: "../python-app", executable: "uvicorn", args: ["main:app", "--host", "0.0.0.0", "--port", "8000"]);
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
// TypeScript: pass additional arguments via withArgs after creationconst python = await builder.addPythonExecutable("python-tool", "../python-app", "uvicorn");await python.withArgs(["main:app", "--host", "0.0.0.0", "--port", "8000"]);
await builder.build().run();Add Uvicorn app
Section titled “Add Uvicorn app”For ASGI web frameworks like FastAPI, Starlette, and Quart, use AddUvicornApp which pre-configures Uvicorn as the ASGI server:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddUvicornApp( name: "python-api", projectDirectory: "../python-app", appName: "main:app") .WithHttpEndpoint(port: 8000, env: "PORT");
builder.AddProject<Projects.ExampleProject>("example") .WithReference(python);
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addUvicornApp("python-api", "../python-app", "main:app");await python.withHttpEndpoint({ port: 8000, env: "PORT" });
const example = await builder.addProject("example", "../ExampleProject/ExampleProject.csproj");await example.withReference(python);
await builder.build().run();AddUvicornApp / addUvicornApp requires:
- name — the resource name shown in the Aspire dashboard
- projectDirectory / appDirectory — path to the directory containing your Python application
- appName / app — the ASGI application in
module:variableformat (for example,main:appfor anappvariable inmain.py)
Uvicorn configuration
Section titled “Uvicorn configuration”Configure Uvicorn worker count and log level through environment variables:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddUvicornApp("python-api", "../python-app", "main:app") .WithHttpEndpoint(port: 8000, env: "PORT") .WithEnvironment("UVICORN_WORKERS", "4") .WithEnvironment("UVICORN_LOG_LEVEL", "info");
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addUvicornApp("python-api", "../python-app", "main:app");await python.withHttpEndpoint({ port: 8000, env: "PORT" });await python.withEnvironment("UVICORN_WORKERS", "4");await python.withEnvironment("UVICORN_LOG_LEVEL", "info");
await builder.build().run();Common Uvicorn environment variables:
- UVICORN_PORT — port to listen on
- UVICORN_HOST — host to bind to (default:
127.0.0.1) - UVICORN_WORKERS — number of worker processes
- UVICORN_LOG_LEVEL — logging level (
debug,info,warning,error)
Virtual environment management
Section titled “Virtual environment management”The Python hosting integration automatically detects and uses a virtual environment in the project directory. By default, if a requirements.txt or pyproject.toml is found, Aspire creates and activates a virtual environment before starting the app.
Custom virtual environment
Section titled “Custom virtual environment”To specify a custom virtual environment path, use WithVirtualEnvironment:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddPythonApp("python-api", "../python-app", "main.py") .WithVirtualEnvironment("../python-app/.venv");
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addPythonApp("python-api", "../python-app", "main.py");await python.withVirtualEnvironment("../python-app/.venv");
await builder.build().run();Disable virtual environment
Section titled “Disable virtual environment”To opt out of automatic virtual environment management, call WithoutVirtualEnvironment in C#:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddPythonApp("python-api", "../python-app", "main.py") .WithoutVirtualEnvironment();
builder.Build().Run();Package management
Section titled “Package management”uv package manager
Section titled “uv package manager”Use WithUv to opt into the uv package manager, which installs dependencies significantly faster than pip:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddUvicornApp("python-api", "../python-app", "main:app") .WithUv() .WithHttpEndpoint(port: 8000, env: "PORT");
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addUvicornApp("python-api", "../python-app", "main:app");await python.withUv();await python.withHttpEndpoint({ port: 8000, env: "PORT" });
await builder.build().run();pip package manager
Section titled “pip package manager”Use WithPip to explicitly select pip:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddPythonApp("python-api", "../python-app", "main.py") .WithPip() .WithHttpEndpoint(port: 8000, env: "PORT");
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addPythonApp("python-api", "../python-app", "main.py");await python.withPip();await python.withHttpEndpoint({ port: 8000, env: "PORT" });
await builder.build().run();Configure endpoints
Section titled “Configure endpoints”Python apps typically read the port from an environment variable. Use WithHttpEndpoint to declare the port and inject the variable name:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddUvicornApp("python-api", "../python-app", "main:app") .WithHttpEndpoint(port: 8000, env: "PORT");
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addUvicornApp("python-api", "../python-app", "main:app");await python.withHttpEndpoint({ port: 8000, env: "PORT" });
await builder.build().run();Multiple endpoints
Section titled “Multiple endpoints”A Python app can expose more than one endpoint:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddPythonApp("python-api", "../python-app", "main.py") .WithHttpEndpoint(port: 8000, env: "HTTP_PORT", name: "http") .WithHttpEndpoint(port: 8443, env: "HTTPS_PORT", name: "https");
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addPythonApp("python-api", "../python-app", "main.py");await python.withHttpEndpoint({ port: 8000, env: "HTTP_PORT", name: "http" });await python.withHttpEndpoint({ port: 8443, env: "HTTPS_PORT", name: "https" });
await builder.build().run();Health checks
Section titled “Health checks”Declare an HTTP health-check endpoint so Aspire knows when the app is ready:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddUvicornApp("python-api", "../python-app", "main:app") .WithHttpEndpoint(port: 8000, env: "PORT") .WithHttpHealthCheck("/health");
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addUvicornApp("python-api", "../python-app", "main:app");await python.withHttpEndpoint({ port: 8000, env: "PORT" });await python.withHttpHealthCheck("/health");
await builder.build().run();Environment variables
Section titled “Environment variables”Inject arbitrary environment variables with WithEnvironment:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddPythonApp("python-api", "../python-app", "main.py") .WithEnvironment("DEBUG", "true") .WithEnvironment("LOG_LEVEL", "debug");
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addPythonApp("python-api", "../python-app", "main.py");await python.withEnvironment("DEBUG", "true");await python.withEnvironment("LOG_LEVEL", "debug");
await builder.build().run();Service discovery
Section titled “Service discovery”Reference other Aspire resources from a Python app using WithReference. Aspire injects the connection string as the ConnectionStrings__<resourcename> environment variable in the Python process:
var builder = DistributedApplication.CreateBuilder(args);
var db = builder.AddPostgres("postgres") .AddDatabase("mydb");
var python = builder.AddPythonApp("python-api", "../python-app", "main.py") .WithReference(db);
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const postgres = await builder.addPostgres("postgres");const db = await postgres.addDatabase("mydb");
const python = await builder.addPythonApp("python-api", "../python-app", "main.py");await python.withReference(db);
await builder.build().run();Read the connection string in Python using the ConnectionStrings__mydb environment variable (double-underscore separator for Python/shell environments):
import os
connection_string = os.environ.get("ConnectionStrings__mydb")HTTPS configuration
Section titled “HTTPS configuration”By default, Python apps run over HTTP in local development. To enable HTTPS, use WithHttpsEndpoint together with WithHttpsDeveloperCertificate:
var builder = DistributedApplication.CreateBuilder(args);
var python = builder.AddUvicornApp("python-api", "../python-app", "main:app") .WithHttpsEndpoint(port: 8443, env: "PORT") .WithHttpsDeveloperCertificate();
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const python = await builder.addUvicornApp("python-api", "../python-app", "main:app");await python.withHttpsEndpoint({ port: 8443, env: "PORT" });await python.withHttpsDeveloperCertificate();
await builder.build().run();WithHttpsDeveloperCertificate exports the ASP.NET Core development certificate and injects it into the Python process as environment variables. Read those variables in your Uvicorn startup:
import osimport uvicorn
if __name__ == "__main__": ssl_keyfile = os.environ.get("ASPNETCORE_Kestrel__Certificates__Default__KeyPath") ssl_certfile = os.environ.get("ASPNETCORE_Kestrel__Certificates__Default__Path")
uvicorn.run( "main:app", host="0.0.0.0", port=int(os.environ.get("PORT", 8443)), ssl_keyfile=ssl_keyfile, ssl_certfile=ssl_certfile, )Internal versus external service exposure
Section titled “Internal versus external service exposure”By default, Aspire services are only accessible within the distributed application. Use WithExternalHttpEndpoints to expose a service to external traffic:
var builder = DistributedApplication.CreateBuilder(args);
var internalApi = builder.AddUvicornApp("internal-api", "../internal-api", "main:app") .WithHttpEndpoint(port: 8001, env: "PORT");// internalApi is NOT exposed publicly — only reachable by other Aspire resources
var publicApi = builder.AddUvicornApp("public-api", "../public-api", "main:app") .WithHttpEndpoint(port: 8000, env: "PORT") .WithExternalHttpEndpoints();// publicApi IS exposed publicly
builder.AddProject<Projects.WebFrontend>("frontend") .WithReference(internalApi) .WithReference(publicApi);
builder.Build().Run();import { createBuilder } from "./.modules/aspire.js";
const builder = await createBuilder();
const internalApi = await builder.addUvicornApp("internal-api", "../internal-api", "main:app");await internalApi.withHttpEndpoint({ port: 8001, env: "PORT" });// internalApi is NOT exposed publicly — only reachable by other Aspire resources
const publicApi = await builder.addUvicornApp("public-api", "../public-api", "main:app");await publicApi.withHttpEndpoint({ port: 8000, env: "PORT" });await publicApi.withExternalHttpEndpoints();// publicApi IS exposed publicly
const frontend = await builder.addProject("frontend", "../WebFrontend/WebFrontend.csproj");await frontend.withReference(internalApi);await frontend.withReference(publicApi);
await builder.build().run();Debugging
Section titled “Debugging”The Python hosting integration provides full debugging support in Visual Studio Code:
- Install the Aspire VS Code extension
- Set breakpoints in your Python code
- Run the Aspire app host
- The debugger automatically attaches to your Python application
Deployment
Section titled “Deployment”When deploying your Aspire application, the Python hosting integration automatically generates production-ready Dockerfiles for your Python services:
# Auto-generated DockerfileFROM python:3.12-slim
WORKDIR /appCOPY requirements.txt .RUN pip install -r requirements.txt
COPY . .CMD ["python", "main.py"]