在 Python 中协调 .NET Aspire 应用
本文介绍如何在 Python 应用主机中使用 .NET Aspire 应用。 本文中的示例应用演示如何启动 Python 应用程序。 Python 的 .NET Aspire 扩展需要使用虚拟环境。
先决条件
若要使用 .NET.NET Aspire,需要在本地安装以下各项:
- .NET 8.0 或 .NET 9.0
- 符合 OCI 的容器运行时,例如:
- 集成开发人员环境(IDE)或代码编辑器,例如:
- Visual Studio 2022 17.9 或更高版本(可选)
-
Visual Studio Code (可选)
- C# Dev Kit:扩展(可选)
- JetBrains Rider 带有 .NET.NET Aspire 插件(可选)
有关详细信息,请参阅 .NET.NET Aspire 设置和工具,以及 .NET.NET Aspire SDK。
此外,需要在计算机上安装 Python。 本文中的示例应用是使用 Python 版本 3.12.4 和 pip 版本 24.1.2 生成的。 若要验证 Python 和 pip 版本,请运行以下命令:
python --version
pip --version
若要下载 Python(包括 pip
),请参阅 Python 下载页面。
使用模板创建 .NET.NET Aspire 项目
要在 Python 中启动 .NET Aspire 项目,首先使用入门模板创建 .NET Aspire 应用程序主机:
dotnet new aspire -o PythonSample
在同一终端会话中,将目录更改为新创建的项目:
cd PythonSample
创建模板后,使用以下命令启动应用主机,以确保应用主机和 .NET.NET Aspire 仪表板 成功启动:
dotnet run --project PythonSample.AppHost/PythonSample.AppHost.csproj
应用主机启动后,应该可以单击控制台输出中的仪表板链接。 此时,仪表板不会显示任何资源。 在终端中按 Ctrl + C,以停止应用主机。
准备 Python 应用程序
在创建 .NET Aspire 解决方案的上一个终端会话中,创建一个新目录以包含 Python 源代码。
mkdir hello-python
将目录更改为新创建的 hello-python 目录:
cd hello-python
初始化 Python 虚拟环境
若要使用 Python 应用,它们需要位于虚拟环境中。 若要创建虚拟环境,请运行以下命令:
python -m venv .venv
有关虚拟环境的详细信息,请参阅 Python:在虚拟环境中使用 pip 和 venv 安装包。
若要激活虚拟环境,启用包的安装和使用,请运行以下命令:
source .venv/bin/activate
运行以下命令,确保虚拟环境中的 pip up-to-date:
python -m pip install --upgrade pip
安装 Python 包
通过在 hello-python 目录中创建 requirements.txt 文件并添加以下行来安装 Flask 包:
Flask==3.0.3
然后,运行以下命令安装 Flask 包:
python -m pip install -r requirements.txt
安装 Flask 后,在 hello-python 目录中创建名为 main.py 的新文件,并添加以下代码:
import os
import flask
app = flask.Flask(__name__)
@app.route('/', methods=['GET'])
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8111))
app.run(host='0.0.0.0', port=port)
前面的代码创建一个简单的 Flask 应用,该应用侦听端口 8111,并在访问根终结点时返回消息 "Hello, World!"
。
更新应用主机项目
运行以下命令安装 Python 托管包:
dotnet add ../PythonSample.AppHost/PythonSample.AppHost.csproj package Aspire.Hosting.Python --version 9.0.0
安装包后,项目 XML 应具有类似于以下内容的新包引用:
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.1.0" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>5fd92a87-fff8-4a09-9f6e-2c0d656e25ba</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.1.0" />
<PackageReference Include="Aspire.Hosting.Python" Version="9.1.0" />
</ItemGroup>
</Project>
通过调用 API 并指定项目名称、项目路径和入口点文件,更新应用主机 Python 文件以包括 AddPythonApp
项目:
using Microsoft.Extensions.Hosting;
var builder = DistributedApplication.CreateBuilder(args);
#pragma warning disable ASPIREHOSTINGPYTHON001
var pythonapp = builder.AddPythonApp("hello-python", "../hello-python", "main.py")
.WithHttpEndpoint(env: "PORT")
.WithExternalHttpEndpoints()
.WithOtlpExporter();
#pragma warning restore ASPIREHOSTINGPYTHON001
if (builder.ExecutionContext.IsRunMode && builder.Environment.IsDevelopment())
{
pythonapp.WithEnvironment("DEBUG", "True");
}
builder.Build().Run();
重要
AddPythonApp
API 是实验性的,将来的版本可能会更改。 有关详细信息,请参阅 ASPIREHOSTINGPYTHON001。
运行应用
添加 Python 托管包、更新应用主机 Program.cs 文件并创建 Python 项目后,即可运行应用主机:
dotnet run --project ../PythonSample.AppHost/PythonSample.AppHost.csproj
通过单击控制台输出中的链接启动仪表板。 仪表板应将 Python 项目显示为资源。
选择 终结点 链接,在新浏览器选项卡中打开 hello-python
终结点。浏览器应显示消息“Hello, World!”:
在终端中按 Ctrl + C,以停止应用主机。
添加遥测支持。
为了增强可观测性,请添加遥测以帮助监控依赖的 Python 应用。 在 Python 项目中,将以下 OpenTelemetry 包添加为 requirements.txt 文件中的依赖项:
Flask==3.0.3
opentelemetry-distro
opentelemetry-exporter-otlp-proto-grpc
opentelemetry-instrumentation-flask
gunicorn
之前的要求更新中,添加了 OpenTelemetry 包和 OTLP 导出器。 接下来,运行以下命令,将 Python 应用要求重新安装到虚拟环境中:
python -m pip install -r requirements.txt
上述命令在虚拟环境中安装 OpenTelemetry 包和 OTLP 导出程序。 通过将现有 Python 代码替换为以下内容,更新 OpenTelemetry 应用以包括 代码:
import os
import logging
import flask
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.flask import FlaskInstrumentor
app = flask.Flask(__name__)
trace.set_tracer_provider(TracerProvider())
otlpExporter = OTLPSpanExporter()
processor = BatchSpanProcessor(otlpExporter)
trace.get_tracer_provider().add_span_processor(processor)
FlaskInstrumentor().instrument_app(app)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.route('/', methods=['GET'])
def hello_world():
logger.info("request received!")
return 'Hello, World!'
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8111))
debug = bool(os.environ.get('DEBUG', False))
host = os.environ.get('HOST', '127.0.0.1')
app.run(port=port, debug=debug, host=host)
更新应用主机项目的 launchSettings.json 文件以包含 ASPIRE_ALLOW_UNSECURED_TRANSPORT
环境变量:
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:17171;http://localhost:15209",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21171",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22122"
}
},
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:15209",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19171",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20208",
"ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true"
}
}
}
}
ASPIRE_ALLOW_UNSECURED_TRANSPORT
变量是必需的,因为在本地运行 OpenTelemetry 客户端时,Python 会拒绝本地开发证书。 再次启动 应用主机:
dotnet run --project ../PythonSample.AppHost/PythonSample.AppHost.csproj
应用主机启动后,导航到仪表板并注意,除了控制台日志输出之外,结构化日志记录也会路由到仪表板。
总结
虽然本文未讨论几个注意事项,但你已了解如何生成与 .NET Aspire集成的 Python 解决方案。 你还了解了如何使用 AddPythonApp
API 托管 Python 应用。