diff --git a/.gitignore b/.gitignore index 8a30d25..b90d767 100644 --- a/.gitignore +++ b/.gitignore @@ -396,3 +396,6 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml + +# Python Virtual Environments +.venv diff --git a/Directory.Packages.props b/Directory.Packages.props index 875f181..ed76f06 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -2,34 +2,36 @@ true true - 8.6.0 - 8.2.0 + 9.0.0-rc.1.24509.13 9.0.0-preview.9.24507.7 - - - - - - - - - + + + + + + + + + + + + - - + + - - + + - - - + + + @@ -40,10 +42,11 @@ - + + @@ -51,11 +54,11 @@ + - diff --git a/nuget.config b/nuget.config index d076cae..45d2e5d 100644 --- a/nuget.config +++ b/nuget.config @@ -1,9 +1,10 @@ - + + @@ -12,5 +13,8 @@ + + + diff --git a/seeddata/DataGenerator/DataGenerator.csproj b/seeddata/DataGenerator/DataGenerator.csproj index 995784a..dcb3e98 100644 --- a/seeddata/DataGenerator/DataGenerator.csproj +++ b/seeddata/DataGenerator/DataGenerator.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable enable eShopSupport.DataGenerator diff --git a/src/AppHost/AppHost.csproj b/src/AppHost/AppHost.csproj index 7dae6ee..8a53487 100644 --- a/src/AppHost/AppHost.csproj +++ b/src/AppHost/AppHost.csproj @@ -1,27 +1,25 @@  - + Exe - net8.0 + net9.0 enable enable true dbe89ad9-90f1-44de-9646-7e98b2d8c69d - + - - - + \ No newline at end of file diff --git a/src/AppHost/Ollama/OllamaResourceExtensions.cs b/src/AppHost/Ollama/OllamaResourceExtensions.cs index c22f708..f2c9e16 100644 --- a/src/AppHost/Ollama/OllamaResourceExtensions.cs +++ b/src/AppHost/Ollama/OllamaResourceExtensions.cs @@ -140,7 +140,7 @@ private static async Task DownloadModelAsync(ILogger logger, EndpointReference h var httpClient = new HttpClient { Timeout = TimeSpan.FromDays(1) }; var request = new HttpRequestMessage(HttpMethod.Post, $"{httpEndpoint.Url}/api/pull") { Content = JsonContent.Create(new { name = modelName }) }; - var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); + var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); var responseContentStream = await response.Content.ReadAsStreamAsync(cancellationToken); var streamReader = new StreamReader(responseContentStream); var line = (string?)null; diff --git a/src/AppHost/Program.cs b/src/AppHost/Program.cs index e49e09d..aa38fc0 100644 --- a/src/AppHost/Program.cs +++ b/src/AppHost/Program.cs @@ -43,8 +43,19 @@ var blobStorage = storage.AddBlobs("eshopsupport-blobs"); -var pythonInference = builder.AddPythonUvicornApp("python-inference", - Path.Combine("..", "PythonInference"), port: 62394); +var stage = builder.ExecutionContext.IsRunMode ? "base" : /* default stage */ null; +var pythonInference = builder.AddDockerfile("python-inference", "../PythonInference", /* default dockerfile */ null, stage) + .WithHttpEndpoint(port: 57000, targetPort: 8000) + .WithContainerRuntimeArgs("--gpus=all") + .WithLifetime(ContainerLifetime.Persistent); + +if (builder.ExecutionContext.IsRunMode) +{ + // Mount app files into the container & enable auto-reload when running in development + pythonInference + .WithBindMount("../PythonInference", "/app") + .WithArgs("--reload"); +} var redis = builder.AddRedis("redis"); @@ -53,7 +64,7 @@ .WithReference(chatCompletion) .WithReference(blobStorage) .WithReference(vectorDb) - .WithReference(pythonInference) + .WithReference(pythonInference.GetEndpoint("http")) .WithReference(redis) .WithEnvironment("IdentityUrl", identityEndpoint) .WithEnvironment("ImportInitialDataDir", Path.Combine(builder.AppHostDirectory, "..", "..", "seeddata", isE2ETest ? "test" : "dev")); diff --git a/src/AppHost/Python/PythonUvicornAppResourceBuilderExtensions.cs b/src/AppHost/Python/PythonUvicornAppResourceBuilderExtensions.cs deleted file mode 100644 index b3a2713..0000000 --- a/src/AppHost/Python/PythonUvicornAppResourceBuilderExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Aspire.Hosting; - -public static class PythonUvicornAppResourceBuilderExtensions -{ - public static IResourceBuilder AddPythonUvicornApp(this IDistributedApplicationBuilder builder, string name, string workingDirectory, int? port = default, int? targetPort = default) - { - return builder.AddResource(new PythonUvicornAppResource(name, "python", workingDirectory)) - .WithArgs("-m", "uvicorn", "main:app") - .WithHttpEndpoint(env: "UVICORN_PORT", port: port, targetPort: targetPort); - } -} - -public class PythonUvicornAppResource(string name, string command, string workingDirectory) - : ExecutableResource(name, command, workingDirectory), IResourceWithServiceDiscovery -{ -} diff --git a/src/Backend/Backend.csproj b/src/Backend/Backend.csproj index 444fb65..b9155fe 100644 --- a/src/Backend/Backend.csproj +++ b/src/Backend/Backend.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable eShopSupport.Backend diff --git a/src/CustomerWebUI/CustomerWebUI.csproj b/src/CustomerWebUI/CustomerWebUI.csproj index d5f3875..74f8f2a 100644 --- a/src/CustomerWebUI/CustomerWebUI.csproj +++ b/src/CustomerWebUI/CustomerWebUI.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable diff --git a/src/DataIngestor/DataIngestor.csproj b/src/DataIngestor/DataIngestor.csproj index c9d6913..aafccb1 100644 --- a/src/DataIngestor/DataIngestor.csproj +++ b/src/DataIngestor/DataIngestor.csproj @@ -1,27 +1,21 @@  - Exe - net8.0 + net9.0 enable enable eShopSupport.DataIngestor $(SolutionDir)\seeddata\DataGenerator\output - $(NoWarn);SKEXP0001;SKEXP0020;SKEXP0050 - true + $(NoWarn);SKEXP0001;SKEXP0050 - - + + - - - - diff --git a/src/Evaluator/Evaluator.csproj b/src/Evaluator/Evaluator.csproj index cf012a8..eb29091 100644 --- a/src/Evaluator/Evaluator.csproj +++ b/src/Evaluator/Evaluator.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable enable eShopSupport.Evaluator diff --git a/src/IdentityServer/IdentityServer.csproj b/src/IdentityServer/IdentityServer.csproj index d826b50..1752833 100644 --- a/src/IdentityServer/IdentityServer.csproj +++ b/src/IdentityServer/IdentityServer.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable diff --git a/src/PythonInference/Dockerfile b/src/PythonInference/Dockerfile new file mode 100644 index 0000000..b66c21f --- /dev/null +++ b/src/PythonInference/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.12.5-slim AS base + +# Set the working directory, the app files could be bind-mounted here +WORKDIR /app + +# Copy the requirements file +COPY requirements.txt . + +# Install dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Ensure the server is accessible from outside the container +ENV UVICORN_HOST=0.0.0.0 + +# Set the entry point to run the application +ENTRYPOINT ["python", "-m", "uvicorn", "main:app"] + +CMD [] + +FROM base AS publish + +COPY . . \ No newline at end of file diff --git a/src/PythonInference/PythonInference.pyproj b/src/PythonInference/PythonInference.pyproj index 9a50be7..90b7cbf 100644 --- a/src/PythonInference/PythonInference.pyproj +++ b/src/PythonInference/PythonInference.pyproj @@ -28,5 +28,8 @@ + + + \ No newline at end of file diff --git a/src/ServiceDefaults/Extensions.cs b/src/ServiceDefaults/Extensions.cs index ba0978f..a58599e 100644 --- a/src/ServiceDefaults/Extensions.cs +++ b/src/ServiceDefaults/Extensions.cs @@ -49,7 +49,8 @@ public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicati }) .WithTracing(tracing => { - tracing.AddAspNetCoreInstrumentation() + tracing.AddSource(builder.Environment.ApplicationName) + .AddAspNetCoreInstrumentation() // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) //.AddGrpcClientInstrumentation() .AddHttpClientInstrumentation() diff --git a/src/ServiceDefaults/ServiceDefaults.csproj b/src/ServiceDefaults/ServiceDefaults.csproj index ab367e1..562832f 100644 --- a/src/ServiceDefaults/ServiceDefaults.csproj +++ b/src/ServiceDefaults/ServiceDefaults.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable true diff --git a/src/StaffWebUI/StaffWebUI.csproj b/src/StaffWebUI/StaffWebUI.csproj index 6d060df..75d0db5 100644 --- a/src/StaffWebUI/StaffWebUI.csproj +++ b/src/StaffWebUI/StaffWebUI.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable eShopSupport.StaffWebUI diff --git a/test/E2ETest/E2ETest.csproj b/test/E2ETest/E2ETest.csproj index 9e2dca5..6dda83a 100644 --- a/test/E2ETest/E2ETest.csproj +++ b/test/E2ETest/E2ETest.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable enable diff --git a/test/E2ETest/Infrastructure/AppHostFixture.cs b/test/E2ETest/Infrastructure/AppHostFixture.cs index f2520a8..e2a80ba 100644 --- a/test/E2ETest/Infrastructure/AppHostFixture.cs +++ b/test/E2ETest/Infrastructure/AppHostFixture.cs @@ -1,4 +1,5 @@ -using Aspire.Hosting.Testing; +using Aspire.Hosting; +using Aspire.Hosting.Testing; using eShopSupport.ServiceDefaults.Clients.Backend; using IdentityModel.Client; @@ -21,7 +22,7 @@ private async Task InitializeAsync() Environment.CurrentDirectory = Projects.AppHost.ProjectPath; Environment.SetEnvironmentVariable("E2E_TEST", "true"); Environment.SetEnvironmentVariable("E2E_TEST_CHAT_COMPLETION_CACHE_DIR", - Path.Combine(Projects.E2ETest.ProjectPath, "ChatCompletionCache")); + Path.Combine(Projects.AppHost.ProjectPath, "ChatCompletionCache")); var builder = await DistributedApplicationTestingBuilder.CreateAsync(); var app = await builder.BuildAsync(); await app.StartAsync();