Skip to content

Import samples from aspire-13-samples#1547

Open
IEvangelist wants to merge 9 commits intomainfrom
dapine/import-aspire-13-samples
Open

Import samples from aspire-13-samples#1547
IEvangelist wants to merge 9 commits intomainfrom
dapine/import-aspire-13-samples

Conversation

@IEvangelist
Copy link
Copy Markdown
Member

Summary

  • import 11 file-based Aspire samples from davidfowl/aspire-13-samples
  • normalize imported AppHost package directives to 13.2.2 and flatten image-gallery under samples/
  • add the new samples to the root README sample catalog

Validation

  • .\build\build.cmd
  • dotnet test .\tests\SamplesTests.slnx -nologo -m:1 -nr:false -p:UseSharedCompilation=false

IEvangelist and others added 2 commits April 13, 2026 09:35
Import 11 file-based Aspire samples from davidfowl/aspire-13-samples,
normalize their AppHost package directives to 13.2.2, flatten
image-gallery under samples/, and add the new entries to the root sample
index.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist IEvangelist force-pushed the dapine/import-aspire-13-samples branch from c44bd61 to 50ab10d Compare April 13, 2026 15:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist IEvangelist marked this pull request as ready for review April 13, 2026 17:04
Copilot AI review requested due to automatic review settings April 13, 2026 17:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Imports multiple Aspire 13.x file-based samples (TypeScript AppHosts and polyglot services), normalizes pinned package directives/SDK versions, and updates the build + catalog to recognize and build the new sample shapes.

Changes:

  • Added new samples (polyglot task queue, Node+Redis, Go API, image gallery) including their AppHosts, services, and frontends.
  • Updated build pipeline to detect/build single-file TypeScript AppHosts (apphost.ts) alongside single-file C# AppHosts (apphost.cs).
  • Updated root README sample catalog with the newly imported samples.

Reviewed changes

Copilot reviewed 84 out of 218 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
samples/polyglot-task-queue/worker-python/pyproject.toml Adds Python worker packaging (deps + dev deps) for the sample.
samples/polyglot-task-queue/worker-python/main.py Implements Python RabbitMQ worker with OpenTelemetry propagation.
samples/polyglot-task-queue/worker-python/.python-version Pins Python version for the sample.
samples/polyglot-task-queue/worker-csharp/worker-csharp.csproj Adds C# worker project and NuGet dependencies.
samples/polyglot-task-queue/worker-csharp/Program.cs Implements C# RabbitMQ worker with OpenTelemetry context propagation.
samples/polyglot-task-queue/worker-csharp/Extensions.cs Adds “service defaults” helpers (OTel, health checks, discovery).
samples/polyglot-task-queue/tsconfig.apphost.json TypeScript build config for the TS AppHost.
samples/polyglot-task-queue/package.json Defines Node tooling/scripts for the TS AppHost (lint/build/start).
samples/polyglot-task-queue/frontend/vite.config.ts Configures Vite dev proxy for the task queue UI.
samples/polyglot-task-queue/frontend/tsconfig.node.json TS config for Vite config typing/build.
samples/polyglot-task-queue/frontend/tsconfig.json TS config for the React frontend.
samples/polyglot-task-queue/frontend/src/style.css Adds UI styling for the task queue frontend.
samples/polyglot-task-queue/frontend/src/main.tsx React entrypoint for the task queue UI.
samples/polyglot-task-queue/frontend/src/App.tsx Implements the task queue UI and polling logic.
samples/polyglot-task-queue/frontend/package.json Frontend dependencies and build scripts.
samples/polyglot-task-queue/frontend/index.html HTML entry for the Vite React frontend.
samples/polyglot-task-queue/eslint.config.mjs ESLint config for the TS AppHost.
samples/polyglot-task-queue/aspire.config.json Pins Aspire SDK/packages and declares TS AppHost configuration.
samples/polyglot-task-queue/apphost.ts TypeScript AppHost wiring RabbitMQ, API, frontend, and workers.
samples/polyglot-task-queue/api/telemetry.js Adds alternate Node OTel setup file for the API.
samples/polyglot-task-queue/api/package.json Declares Node API dependencies including OpenTelemetry and AMQP.
samples/polyglot-task-queue/api/instrumentation.js Adds Node OTel SDK initialization and exporter wiring.
samples/polyglot-task-queue/api/index.js Implements Express API + RabbitMQ consumers/publishers with tracing.
samples/polyglot-task-queue/api/Properties/launchSettings.json Local dev launch settings for the Node API project folder.
samples/polyglot-task-queue/README.md Documents sample architecture, run/deploy commands, and patterns.
samples/polyglot-task-queue/.aspire/settings.json Aspire tooling settings for the sample.
samples/node-express-redis/tsconfig.apphost.json TypeScript build config for the TS AppHost.
samples/node-express-redis/package.json Node tooling/scripts for the TS AppHost.
samples/node-express-redis/frontend/vite.config.ts Configures Vite dev proxy for the visit counter UI.
samples/node-express-redis/frontend/tsconfig.node.json TS config for Vite config typing/build.
samples/node-express-redis/frontend/tsconfig.json TS config for the React frontend.
samples/node-express-redis/frontend/src/style.css Adds UI styling for the visit counter frontend.
samples/node-express-redis/frontend/src/main.tsx React entrypoint for the visit counter UI.
samples/node-express-redis/frontend/src/App.tsx Implements visit counter UI and API calls.
samples/node-express-redis/frontend/package.json Frontend dependencies and build scripts.
samples/node-express-redis/frontend/index.html HTML entry for the Vite React frontend.
samples/node-express-redis/eslint.config.mjs ESLint config for the TS AppHost.
samples/node-express-redis/aspire.config.json Pins Aspire SDK/packages and declares TS AppHost configuration.
samples/node-express-redis/apphost.ts TypeScript AppHost wiring Redis, API, frontend, and YARP.
samples/node-express-redis/api/package.json Node API dependencies for Express + Redis.
samples/node-express-redis/api/index.js Implements Express API with Redis-backed counters.
samples/node-express-redis/README.md Documents sample architecture and Aspire patterns.
samples/node-express-redis/.aspire/settings.json Aspire tooling settings for the sample.
samples/image-gallery/worker/worker.csproj Adds image gallery worker project and dependencies.
samples/image-gallery/worker/appsettings.json Worker logging configuration.
samples/image-gallery/worker/Services/ThumbnailWorker.cs Implements queue-driven thumbnail generation worker.
samples/image-gallery/worker/Properties/launchSettings.json Local dev launch settings for worker.
samples/image-gallery/worker/Program.cs Worker host wiring (service defaults, storage, SQL, hosted service).
samples/image-gallery/worker/Models/Image.cs Worker-side EF model for images.
samples/image-gallery/worker/Data/ImageDbContext.cs Worker EF Core DbContext configuration.
samples/image-gallery/shared/Extensions.cs Shared “service defaults” helpers for API/worker.
samples/image-gallery/frontend/vite.config.ts Vite proxy to backend API for local dev.
samples/image-gallery/frontend/tsconfig.node.json TS config for Vite config typing/build.
samples/image-gallery/frontend/tsconfig.json TS config for the React frontend.
samples/image-gallery/frontend/src/main.tsx React entrypoint for image gallery UI.
samples/image-gallery/frontend/src/App.tsx Implements upload/gallery UI including antiforgery token usage.
samples/image-gallery/frontend/src/App.css UI styling for image gallery.
samples/image-gallery/frontend/package.json Frontend dependencies and build scripts.
samples/image-gallery/frontend/index.html HTML entry for the Vite React frontend.
samples/image-gallery/apphost.run.json Run-time launch profile for the C# AppHost.
samples/image-gallery/apphost.cs C# AppHost wiring Azure resources, API, frontend, and job worker.
samples/image-gallery/api/api.csproj Adds image gallery API project and dependencies.
samples/image-gallery/api/Services/DatabaseInitializer.cs Adds startup database init/migration hosted service.
samples/image-gallery/api/Properties/launchSettings.json Local dev launch settings for API.
samples/image-gallery/api/Program.cs API host wiring including antiforgery, OpenAPI, and endpoints.
samples/image-gallery/api/Models/ImageDto.cs Adds DTO for image API responses.
samples/image-gallery/api/Models/Image.cs API-side EF model for images.
samples/image-gallery/api/Extensions/ImageEndpoints.cs Implements image API endpoints including upload/delete/streaming.
samples/image-gallery/api/Data/ImageDbContext.cs API EF Core DbContext configuration.
samples/image-gallery/README.md Documents event-triggered job architecture and security notes.
samples/image-gallery/.aspire/settings.json Aspire tooling settings for the sample.
samples/golang-api/tsconfig.apphost.json TypeScript build config for the TS AppHost.
samples/golang-api/package.json Node tooling/scripts for the TS AppHost.
samples/golang-api/eslint.config.mjs ESLint config for the TS AppHost.
samples/golang-api/aspire.config.json Pins Aspire SDK and declares TS AppHost configuration.
samples/golang-api/apphost.ts TypeScript AppHost that runs Go locally and Dockerfile on publish.
samples/golang-api/api/main.go Implements Go chi REST API with in-memory store.
samples/golang-api/api/go.mod Go module definition and dependency.
samples/golang-api/api/Dockerfile Dockerfile for publishing the Go API.
samples/golang-api/README.md Documents sample behavior and patterns.
samples/golang-api/.editorconfig Suppresses a diagnostic for Dockerfile builder evaluation types.
samples/golang-api/.aspire/settings.json Aspire tooling settings for the sample.
build/Build.proj Updates sample build to also restore/build TS apphost.ts samples.
README.md Adds newly imported samples to the root sample catalog.
Files not reviewed (8)
  • samples/golang-api/package-lock.json: Language not supported
  • samples/image-gallery/frontend/package-lock.json: Language not supported
  • samples/node-express-redis/api/package-lock.json: Language not supported
  • samples/node-express-redis/frontend/package-lock.json: Language not supported
  • samples/node-express-redis/package-lock.json: Language not supported
  • samples/polyglot-task-queue/api/package-lock.json: Language not supported
  • samples/polyglot-task-queue/frontend/package-lock.json: Language not supported
  • samples/polyglot-task-queue/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)

samples/node-express-redis/.aspire/settings.json:1

  • This directory contains a TypeScript AppHost (apphost.ts), but the Aspire settings reference apphost.cs. Point appHostPath to ../apphost.ts so Aspire tooling runs the intended AppHost.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread samples/image-gallery/api/api.csproj Outdated
Comment thread samples/image-gallery/api/Services/DatabaseInitializer.cs Outdated
Comment thread samples/image-gallery/api/Services/DatabaseInitializer.cs Outdated
Comment on lines +72 to +88
group.MapGet("/images/{id}/thumbnail", async (
int id,
ImageDbContext db,
BlobContainerClient containerClient) =>
{
var image = await db.Images.FindAsync(id);
if (image is null || image.ThumbnailUrl is null)
{
return Results.NotFound();
}

var thumbnailName = image.ThumbnailUrl.Split('/').Last();
var blobClient = containerClient.GetBlobClient(thumbnailName);

var download = await blobClient.DownloadStreamingAsync();
return Results.Stream(download.Value.Content, image.ContentType);
});
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The worker saves thumbnails as JPEG (SaveAsJpegAsync), but the API serves the thumbnail with the original image’s ContentType. This can cause incorrect Content-Type headers and broken rendering/caching (e.g., PNG original but JPEG thumbnail). Either store a thumbnail content-type (and use it here) or serve thumbnails consistently as image/jpeg and ensure the thumbnail blob name/extension aligns with that.

Copilot uses AI. Check for mistakes.
Comment on lines +90 to +97
// Upload image
group.MapPost("/images", async (
IFormFile file,
ImageDbContext db,
BlobContainerClient containerClient,
QueueServiceClient queueService,
ILogger<Program> logger) =>
{
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sample fetches and sends antiforgery tokens from the frontend, but these endpoints don’t appear to be marked to require antiforgery validation. With app.UseAntiforgery(), minimal API endpoints typically need antiforgery metadata (e.g., RequireAntiforgeryToken) to enforce checks. Add antiforgery requirements to the POST/DELETE endpoints so the stated XSRF protection is actually enforced.

Copilot uses AI. Check for mistakes.
Comment on lines +134 to +137
<span className="task-count">
{tasks.filter(t => t.status === 'queued').length} queued,{' '}
{tasks.filter(t => t.status === 'completed').length} completed
</span>
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workers/API publish statuses like processing, skipped, and error, but the UI only styles/counts queued, completed, and failed. This means error tasks won’t be counted/styled correctly (and failed may never be produced). Either standardize on a single status vocabulary across services (e.g., use failed everywhere) or update the UI to handle error/processing/skipped consistently (badges + counts).

Copilot uses AI. Check for mistakes.
Comment thread samples/polyglot-task-queue/api/telemetry.js Outdated
**OpenTelemetry** - Automatic configuration via environment variables:
- `OTEL_EXPORTER_OTLP_ENDPOINT`: Aspire dashboard endpoint
- `OTEL_SERVICE_NAME`: Service identifier for traces

Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment claims withReference(rabbitmq) injects RABBITMQ_URI, but the resource name used in the AppHost is "messaging" and the services read MESSAGING_URI. Update the README to reflect the actual injected env var name to avoid confusing readers.

Copilot uses AI. Check for mistakes.
Comment thread samples/node-express-redis/api/index.js Outdated
Comment thread samples/node-express-redis/api/index.js Outdated
IEvangelist and others added 5 commits April 13, 2026 12:53
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread .github/workflows/ci.yml

- name: Build
run: ${{ matrix.os == 'ubuntu-latest' && './build/build.sh' || '.\build\build.cmd' }}
- name: Restore TypeScript AppHosts
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sebastienros We should improve this.

@@ -0,0 +1,3 @@
{
"appHostPath": "../apphost.ts"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove this now right?

@@ -0,0 +1,3 @@
{
"appHostPath": "../apphost.cs"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is aspire.config.json?

Comment thread README.md Outdated
| [Azure Functions](./samples/aspire-with-azure-functions) | C# | ASP.NET Core, Blazor, Azure Functions, Azure Blob Storage | Shows how to integrate [Azure Functions](https://learn.microsoft.com/azure/azure-functions/functions-overview) with Aspire. |
| [Image Gallery](./samples/image-gallery) | C#, JavaScript, TypeScript | Azure Blob Storage, Azure Queues, Azure SQL, Container Apps Jobs | Upload and process images with event-triggered thumbnail generation using Azure resources and local emulators. |
| [Go API](./samples/golang-api) | Go, C# | Go, chi, Containers | Shows a custom Go integration for running and publishing a Go API with Aspire. |
| [Node + Redis + Vite](./samples/node-express-redis) | JavaScript, TypeScript, C# | Express, Redis, React, YARP | Visit counter sample with an Express API, Redis, and a Vite frontend served through YARP. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few of the new rows in this section still list C# in Languages Used even when the sample is actually TypeScript-hosted and has no C# project (for example node-express-redis, golang-api, python-fastapi-postgres, python-openai-agent, python-script, rag-document-qa-svelte, vite-react-fastapi, and vite-yarp-static). That makes the imported set read as less polyglot / less full-stack JS than it actually is. Can we make this column reflect the languages that are actually present in each sample so the top-level catalog tells the right story?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concretely, I think the top-level README should move away from a single flat table and group samples by scenario so the polyglot story is obvious at a glance. Something like: Full-stack JavaScript / TypeScript, Polyglot full-stack, Backend integrations by language, Cloud / AI / event-driven, and .NET + frontend. Within each section, split Workload languages from AppHost instead of folding them together, and add a Deploy column (Docker Compose, Azure, Run only). That would let samples like node-express-redis read as JavaScript, TypeScript | TypeScript AppHost | Docker Compose instead of looking C#-anchored just because Aspire orchestration exists.

@davidfowl
Copy link
Copy Markdown
Contributor

Here's a concrete sketch of what I mean:

## Browse by scenario
- Full-stack JavaScript / TypeScript
- Polyglot full-stack
- Backend integrations by language
- Cloud / AI / event-driven
- .NET + frontend

## Full-stack JavaScript / TypeScript
| Sample | Workload languages | AppHost | Deploy | Description |
| --- | --- | --- | --- | --- |
| [Node + Redis + Vite](./samples/node-express-redis) | JavaScript, TypeScript | TypeScript | Docker Compose | Express API + React/Vite frontend + Redis behind YARP. |
| [Vite + YARP Static Files](./samples/vite-yarp-static) | JavaScript, TypeScript | TypeScript | Docker Compose | Vite frontend served through YARP in run and publish modes. |

## Polyglot full-stack
| Sample | Workload languages | AppHost | Deploy | Description |
| --- | --- | --- | --- | --- |
| [Vite + React + FastAPI](./samples/vite-react-fastapi) | Python, JavaScript, TypeScript | TypeScript | Docker Compose | React frontend + FastAPI backend behind YARP. |
| [Polyglot Task Queue](./samples/polyglot-task-queue) | JavaScript, Python, C# | TypeScript | Docker Compose | React + Node API + Python/C# workers with RabbitMQ. |
| [RAG Document Q&A](./samples/rag-document-qa-svelte) | Python, JavaScript | TypeScript | Run only | Svelte frontend + FastAPI + Qdrant + OpenAI. |

## Backend integrations by language
| Sample | Primary stack | AppHost | Deploy | Description |
| --- | --- | --- | --- | --- |
| [Go API](./samples/golang-api) | Go | TypeScript | Docker Compose | Go + chi API with Aspire-managed run/publish flows. |
| [Python FastAPI + PostgreSQL](./samples/python-fastapi-postgres) | Python | TypeScript | Docker Compose | FastAPI CRUD API with PostgreSQL and pgAdmin. |
| [Python OpenAI Agent](./samples/python-openai-agent) | Python | TypeScript | Docker Compose | FastAPI AI agent with OpenAI integration. |
| [Python Script](./samples/python-script) | Python | TypeScript | Run only | Minimal Python script sample. |

The important bit is separating workload languages from AppHost so the app code tells the story first.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants