Skip to content

Commit 1e47fcd

Browse files
OTEL for python extensions (#472)
* fixes otel for python extensions * fixes uv
1 parent c936d7e commit 1e47fcd

File tree

6 files changed

+59
-41
lines changed

6 files changed

+59
-41
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#nullable enable
22
Aspire.Hosting.ApplicationModel.UvicornAppResource
3-
Aspire.Hosting.ApplicationModel.UvicornAppResource.UvicornAppResource(string! name, string! workingDirectory) -> void
3+
Aspire.Hosting.ApplicationModel.UvicornAppResource.UvicornAppResource(string! name, string! executablePath, string! workingDirectory) -> void
44
Aspire.Hosting.UvicornAppHostingExtension
5-
static Aspire.Hosting.UvicornAppHostingExtension.AddUvicornApp(this Aspire.Hosting.IDistributedApplicationBuilder! builder, string! name, string! projectDirectory, string! appName, string![]? args = null) -> Aspire.Hosting.ApplicationModel.IResourceBuilder<Aspire.Hosting.ApplicationModel.UvicornAppResource!>!
5+
static Aspire.Hosting.UvicornAppHostingExtension.AddUvicornApp(this Aspire.Hosting.IDistributedApplicationBuilder! builder, string! name, string! projectDirectory, string! appName, params string![]! args) -> Aspire.Hosting.ApplicationModel.IResourceBuilder<Aspire.Hosting.ApplicationModel.UvicornAppResource!>!
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#nullable enable
22
Aspire.Hosting.ApplicationModel.UvAppResource
3-
Aspire.Hosting.ApplicationModel.UvAppResource.UvAppResource(string! name, string! workingDirectory) -> void
3+
Aspire.Hosting.ApplicationModel.UvAppResource.UvAppResource(string! name, string! executablePath, string! workingDirectory) -> void
44
Aspire.Hosting.UvAppHostingExtension
55
static Aspire.Hosting.UvAppHostingExtension.AddUvApp(this Aspire.Hosting.IDistributedApplicationBuilder! builder, string! name, string! projectDirectory, string! scriptPath, params string![]! scriptArgs) -> Aspire.Hosting.ApplicationModel.IResourceBuilder<Aspire.Hosting.ApplicationModel.UvAppResource!>!

src/CommunityToolkit.Aspire.Hosting.Python.Extensions/UvAppHostingExtension.cs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,23 @@ private static IResourceBuilder<UvAppResource> AddUvApp(this IDistributedApplica
5050
: Path.Join(projectDirectory, virtualEnvironmentPath));
5151

5252
var instrumentationExecutable = virtualEnvironment.GetExecutable("opentelemetry-instrument");
53-
// var pythonExecutable = virtualEnvironment.GetRequiredExecutable("python");
54-
// var projectExecutable = instrumentationExecutable ?? pythonExecutable;
53+
var projectExecutable = instrumentationExecutable ?? "uv";
5554

56-
string[] allArgs = args is { Length: > 0 }
57-
? ["run", scriptPath, .. args]
58-
: ["run", scriptPath];
55+
var projectResource = new UvAppResource(name, projectExecutable, projectDirectory);
5956

60-
var projectResource = new UvAppResource(name, projectDirectory);
61-
62-
var resourceBuilder = builder.AddResource(projectResource)
63-
.WithArgs(allArgs)
64-
.WithArgs(context =>
57+
var resourceBuilder = builder.AddResource(projectResource).WithArgs(context =>
58+
{
59+
// If the project is to be automatically instrumented, add the instrumentation executable arguments first.
60+
if (!string.IsNullOrEmpty(instrumentationExecutable))
6561
{
66-
// If the project is to be automatically instrumented, add the instrumentation executable arguments first.
67-
if (!string.IsNullOrEmpty(instrumentationExecutable))
68-
{
69-
AddOpenTelemetryArguments(context);
62+
AddOpenTelemetryArguments(context);
63+
64+
// Add the uvicorn executable as the next argument so we can run the project.
65+
context.Args.Add("uv");
66+
}
7067

71-
// // Add the python executable as the next argument so we can run the project.
72-
// context.Args.Add(pythonExecutable!);
73-
}
74-
});
68+
AddProjectArguments(scriptPath, args, context);
69+
});
7570

7671
if (!string.IsNullOrEmpty(instrumentationExecutable))
7772
{
@@ -85,6 +80,17 @@ private static IResourceBuilder<UvAppResource> AddUvApp(this IDistributedApplica
8580
return resourceBuilder;
8681
}
8782

83+
private static void AddProjectArguments(string scriptPath, string[] scriptArgs, CommandLineArgsCallbackContext context)
84+
{
85+
context.Args.Add("run");
86+
context.Args.Add(scriptPath);
87+
88+
foreach (var arg in scriptArgs)
89+
{
90+
context.Args.Add(arg);
91+
}
92+
}
93+
8894
private static void AddOpenTelemetryArguments(CommandLineArgsCallbackContext context)
8995
{
9096
context.Args.Add("--traces_exporter");

src/CommunityToolkit.Aspire.Hosting.Python.Extensions/UvAppResource.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ namespace Aspire.Hosting.ApplicationModel;
66
/// Represents a Uv application.
77
/// </summary>
88
/// <param name="name">The name of the resource.</param>
9+
/// <param name="executablePath">The path to the executable used to run the python app.</param>
910
/// <param name="workingDirectory">The working directory for uv.</param>
10-
public class UvAppResource(string name, string workingDirectory)
11-
: PythonAppResource(name, "uv", workingDirectory), IResourceWithServiceDiscovery
11+
public class UvAppResource(string name, string executablePath, string workingDirectory)
12+
: PythonAppResource(name, executablePath, workingDirectory), IResourceWithServiceDiscovery
1213
{
1314
internal const string HttpEndpointName = "http";
1415
}

src/CommunityToolkit.Aspire.Hosting.Python.Extensions/UvicornAppHostingExtension.cs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public static IResourceBuilder<UvicornAppResource> AddUvicornApp(
2424
[ResourceName] string name,
2525
string projectDirectory,
2626
string appName,
27-
string[]? args = null)
27+
params string[] args)
2828
{
2929
ArgumentNullException.ThrowIfNull(builder);
3030

@@ -36,7 +36,7 @@ private static IResourceBuilder<UvicornAppResource> AddUvicornApp(this IDistribu
3636
string projectDirectory,
3737
string appName,
3838
string virtualEnvironmentPath,
39-
string[]? args = null)
39+
params string[] args)
4040
{
4141
ArgumentNullException.ThrowIfNull(builder);
4242
ArgumentNullException.ThrowIfNull(appName);
@@ -50,23 +50,23 @@ private static IResourceBuilder<UvicornAppResource> AddUvicornApp(this IDistribu
5050
: Path.Join(projectDirectory, virtualEnvironmentPath));
5151

5252
var instrumentationExecutable = virtualEnvironment.GetExecutable("opentelemetry-instrument");
53+
var projectExecutable = instrumentationExecutable ?? "uvicorn";
5354

54-
string[] allArgs = args is { Length: > 0 }
55-
? [appName, .. args]
56-
: [appName];
55+
var projectResource = new UvicornAppResource(name, projectExecutable, projectDirectory);
5756

58-
var projectResource = new UvicornAppResource(name, projectDirectory);
57+
var resourceBuilder = builder.AddResource(projectResource).WithArgs(context =>
58+
{
59+
// If the project is to be automatically instrumented, add the instrumentation executable arguments first.
60+
if (!string.IsNullOrEmpty(instrumentationExecutable))
61+
{
62+
AddOpenTelemetryArguments(context);
63+
64+
// Add the uvicorn executable as the next argument so we can run the project.
65+
context.Args.Add("uvicorn");
66+
}
5967

60-
var resourceBuilder = builder.AddResource(projectResource)
61-
.WithArgs(allArgs)
62-
.WithArgs(context =>
63-
{
64-
// If the project is to be automatically instrumented, add the instrumentation executable arguments first.
65-
if (!string.IsNullOrEmpty(instrumentationExecutable))
66-
{
67-
AddOpenTelemetryArguments(context);
68-
}
69-
});
68+
AddProjectArguments(appName, args, context);
69+
});
7070

7171
if (!string.IsNullOrEmpty(instrumentationExecutable))
7272
{
@@ -80,6 +80,16 @@ private static IResourceBuilder<UvicornAppResource> AddUvicornApp(this IDistribu
8080
return resourceBuilder;
8181
}
8282

83+
private static void AddProjectArguments(string scriptPath, string[] scriptArgs, CommandLineArgsCallbackContext context)
84+
{
85+
context.Args.Add(scriptPath);
86+
87+
foreach (var arg in scriptArgs)
88+
{
89+
context.Args.Add(arg);
90+
}
91+
}
92+
8393
private static void AddOpenTelemetryArguments(CommandLineArgsCallbackContext context)
8494
{
8595
context.Args.Add("--traces_exporter");

src/CommunityToolkit.Aspire.Hosting.Python.Extensions/UvicornAppResource.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace Aspire.Hosting.ApplicationModel;
66
/// Represents a Uvicorn application.
77
/// </summary>
88
/// <param name="name">The name of the resource.</param>
9+
/// <param name="executablePath">The path to the executable used to run the python app.</param>
910
/// <param name="workingDirectory">The working directory for uvicorn.</param>
10-
public class UvicornAppResource(string name, string workingDirectory)
11-
: PythonAppResource(name, "uvicorn", workingDirectory), IResourceWithServiceDiscovery;
11+
public class UvicornAppResource(string name, string executablePath, string workingDirectory)
12+
: PythonAppResource(name, executablePath, workingDirectory), IResourceWithServiceDiscovery;

0 commit comments

Comments
 (0)