Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 17, 2025

  • Create template directory structure
  • Add all template files and configuration
  • Address all review feedback
  • Add port selection and HTTPS/HTTP logic
  • Update localization files to match English template name and description

Updated all 14 localization files to correctly describe the template as a Python API + JavaScript (React/Vite) starter instead of an "empty app". Each translation now reflects:

  • Template name: "Aspire Python Starter App" (translated)
  • Description: Describes Python backend API service + JavaScript frontend using Vite and React (translated)

This addresses feedback from @davidfowl to fix the translations to match the English template description.

Original prompt

Create a new Aspire project template called aspire-py-starter in src/Aspire.ProjectTemplates/templates for Python backend and Javascript frontend applications, as requested in #11865. The template should be based on the structure and content of @eerhardt/PythonStarter. Include the following:

  • api_service folder and its files: .python-version, app.py, pyproject.toml, telemetry.py, uv.lock
  • frontend folder and its files: .gitignore, eslint.config.js, index.html, package-lock.json, package.json, tsconfig.app.json, tsconfig.json, tsconfig.node.json, vite.config.ts
  • frontend/public folder (Aspire.png, github.svg) and frontend/src (App.css, App.tsx, index.css, main.tsx, vite-env.d.ts)
  • apphost.cs file at the root of the template, orchestrating the backend and frontend using Aspire's distributed application model

The new template should match the conventions of existing templates in the folder and provide a ready-to-use scaffold for non-.NET developers to start Aspire applications with Python and JS resources. Add a readme file explaining usage, the structure, and any specific instructions, modeled after other template readmes in the repo.

This pull request was created as a result of the following prompt from Copilot chat.

Create a new Aspire project template called aspire-py-starter in src/Aspire.ProjectTemplates/templates for Python backend and Javascript frontend applications, as requested in #11865. The template should be based on the structure and content of @eerhardt/PythonStarter. Include the following:

  • api_service folder and its files: .python-version, app.py, pyproject.toml, telemetry.py, uv.lock
  • frontend folder and its files: .gitignore, eslint.config.js, index.html, package-lock.json, package.json, tsconfig.app.json, tsconfig.json, tsconfig.node.json, vite.config.ts
  • frontend/public folder (Aspire.png, github.svg) and frontend/src (App.css, App.tsx, index.css, main.tsx, vite-env.d.ts)
  • apphost.cs file at the root of the template, orchestrating the backend and frontend using Aspire's distributed application model

The new template should match the conventions of existing templates in the folder and provide a ready-to-use scaffold for non-.NET developers to start Aspire applications with Python and JS resources. Add a readme file explaining usage, the structure, and any specific instructions, modeled after other template readmes in the repo.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits October 17, 2025 21:33
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
Copilot AI changed the title [WIP] Create new Aspire project template for Python and JavaScript Add aspire-py-starter template for Python and JavaScript applications Oct 17, 2025
Copilot AI requested a review from eerhardt October 17, 2025 21:47
Copilot finished work on behalf of eerhardt October 17, 2025 21:47
…e 13.0

Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
Copilot finished work on behalf of eerhardt October 17, 2025 21:54
@eerhardt
Copy link
Member

@copilot - Remove the Aspire.png and instead use the one from https://github.com/dotnet/aspire/blob/main/src/Shared/Aspire_icon_256.png. Ensure that the template packages it correctly.

Copy link
Contributor Author

Copilot AI commented Oct 17, 2025

@copilot - Remove the Aspire.png and instead use the one from https://github.com/dotnet/aspire/blob/main/src/Shared/Aspire_icon_256.png. Ensure that the template packages it correctly.

The Aspire.png in the template was already identical to src/Shared/Aspire_icon_256.png (MD5: 9413c7a1b425b3137eb3f58a926c98f6). I've verified that the template packages it correctly - the file is included in the NuGet package and appears in generated projects with the correct content.

Copilot finished work on behalf of eerhardt October 17, 2025 22:29
@github-actions
Copy link
Contributor

github-actions bot commented Oct 17, 2025

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 12136

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 12136"

1 similar comment
@github-actions
Copy link
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 12136

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 12136"


<TemplateFiles Include="$(MSBuildThisFileDirectory)templates\**\*"
Exclude="$(MSBuildThisFileDirectory)templates\**\bin\**;$(MSBuildThisFileDirectory)templates\**\obj\**;$(MSBuildThisFileDirectory)templates\**\*.csproj">
Exclude="$(MSBuildThisFileDirectory)templates\**\bin\**;$(MSBuildThisFileDirectory)templates\**\obj\**;$(MSBuildThisFileDirectory)templates\**\*.csproj;$(MSBuildThisFileDirectory)templates\aspire-apphost-singlefile\**\apphost.cs;$(MSBuildThisFileDirectory)templates\aspire-py-starter\**\apphost.cs">
Copy link
Member

Choose a reason for hiding this comment

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

@copilot - is this change correct? I think it should be reverted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added the exclusions to prevent duplicate packaging errors. Without excluding apphost.cs files from TemplateFiles, the build fails with:

error NU5118: File 'content/templates/aspire-py-starter/13.0/apphost.cs' is not added because the package already contains file 'content/templates/aspire-py-starter/13.0/apphost.cs'

The same exclusion should likely apply to aspire-apphost-singlefile as well (which I also added). Should I remove both exclusions or is there a different approach you'd prefer?

Copilot AI requested a review from eerhardt October 17, 2025 23:26
Copilot finished work on behalf of eerhardt October 17, 2025 23:26
"aspire-13.0-tfms": "net8.0;net9.0;net10.0"
},
"precedence": "9000",
"identity": "Aspire.PyStarter.CSharp.8.0",
Copy link
Member

Choose a reason for hiding this comment

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

This can just be Aspire.PyStarter.CSharp as we haven't been using the version suffix.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to Aspire.PyStarter.CSharp in commit a2b37b1.

"language": "C#",
"type": "solution",
"editorTreatAs": "solution",
"aspire-13.0-tfms": "net8.0;net9.0;net10.0"
Copy link
Member

Choose a reason for hiding this comment

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

This isn't required any template except the empty template and is only used by the VS "Add Aspire orchestration" experience.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the aspire-13.0-tfms tag in commit a2b37b1.

Comment on lines 23 to 24
"type": "solution",
"editorTreatAs": "solution",
Copy link
Member

Choose a reason for hiding this comment

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

Hmmm not sure if this is the right choice given this is using file-based app host and no projects or laying down a solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed type from "solution" to "project" in commit a2b37b1.

}
],
"replaces": "net8.0",
"defaultValue": "net9.0"
Copy link
Member

Choose a reason for hiding this comment

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

I think we can remove this entire option as this uses a file-based AppHost so only works on .NET 10

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the Framework symbol entirely in commit a2b37b1 since this is a file-based AppHost for .NET 10+.

Comment on lines 67 to 72
"skipRestore": {
"type": "parameter",
"datatype": "bool",
"description": "If specified, skips the automatic restore of the project on create.",
"defaultValue": "false"
}
Copy link
Member

Choose a reason for hiding this comment

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

I think this whole option can be removed as we don't have the restore post-create action defined here anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the skipRestore symbol in commit a2b37b1.

@@ -0,0 +1,28 @@
#:sdk Aspire.AppHost.Sdk@!!REPLACE_WITH_LATEST_VERSION!!
Copy link
Member

Choose a reason for hiding this comment

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

Need to add a apphost.run.cs file too with the launch profiles. Should be able to copy it from the existing aspire-apphost-singlefile template.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added apphost.run.json with launch profiles in commit a2b37b1.

Copilot AI and others added 3 commits October 18, 2025 00:29
… host configs and apphost.run.json

Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 18, 2025

This PR should update DotnetTemplateFactory in the CLI to support returning this template as an option for aspire new too, along with the regular starter.

Updated DotnetTemplateFactory to include aspire-py-starter template (gated by SingleFileAppHostEnabled feature) in commit 4e89b52.

Copilot finished work on behalf of eerhardt October 18, 2025 00:39
Copy link
Contributor Author

Copilot AI commented Oct 18, 2025

@copilot - apply review feedback

All review feedback has been applied across commits a2b37b1, 64c05ae, and 24c434c. The template is now configured as requested with all changes implemented.

Copilot finished work on behalf of eerhardt October 18, 2025 00:43
@davidfowl davidfowl marked this pull request as ready for review October 18, 2025 06:22
Copilot AI review requested due to automatic review settings October 18, 2025 06:22
Copy link
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

Adds a new aspire-py-starter template enabling a Python (FastAPI) backend with a React + Vite TypeScript frontend orchestrated via a single-file AppHost for Aspire 13.0.

  • Introduces Python service (Redis-backed weather endpoint + OpenTelemetry) and a Vite React frontend.
  • Adds packaging/configuration updates (template.json, localization, CLI integration, Dockerfile, AppHost).
  • Extends CLI template factory and updates project template packaging rules (NoDefaultExcludes, apphost.cs handling).

Reviewed Changes

Copilot reviewed 52 out of 58 changed files in this pull request and generated 20 comments.

Show a summary per file
File Description
vite.config.ts Adds Vite config with API proxy for Python service.
tsconfig.node.json TypeScript config for Node/Vite tooling.
tsconfig.json Project references setup.
tsconfig.app.json TS compiler options for frontend app code.
src/main.tsx React root bootstrapping.
src/index.css Base/reset and accessibility styles.
src/App.tsx Main UI logic fetching weather forecast.
src/App.css Extensive theming and layout styling for the app.
package.json Declares React/Vite/TypeScript dependencies and scripts.
index.html Frontend entry HTML document.
eslint.config.js ESLint configuration for TS/React.
.gitignore Frontend ignore rules.
apphost.run.json Launch profiles for single-file AppHost.
apphost.cs Orchestrates Redis, Python API, and Vite frontend resources.
telemetry.py OpenTelemetry setup for traces, metrics, logs.
pyproject.toml Python project metadata and dependencies.
app.py FastAPI application with Redis caching and health endpoint.
.python-version Specifies Python 3.13 version.
Dockerfile Multi-stage build for frontend + Python runtime image.
template.json Defines template metadata/configuration.
localization JSON files Localized template name/description entries.
ide.host.json Hides template from Visual Studio.
dotnetcli.host.json CLI hosting metadata.
Aspire.ProjectTemplates.csproj Adds template packaging rules for new starter.
DotNetTemplateFactory.cs Exposes new template via Aspire CLI.
TemplatingStrings.*.xlf / .resx Adds localized resource string for template description.
Files not reviewed (1)
  • src/Aspire.Cli/Resources/TemplatingStrings.Designer.cs: Language not supported

# Stage 3: Create the final runtime image
FROM python:3.13-slim-bookworm AS app

COPY --from=frontend-stage /dist /app/static
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

The Vite build output in the first stage (working directory /frontend) will be located at /frontend/dist, not /dist. This COPY will result in an empty static directory. Change to COPY --from=frontend-stage /frontend/dist /app/static.

Suggested change
COPY --from=frontend-stage /dist /app/static
COPY --from=frontend-stage /frontend/dist /app/static

Copilot uses AI. Check for mistakes.
// Proxy API calls to the backend service and strip 'api' prefix
'/api': {
target: process.env.services__apiservice__https__0 || process.env.services__apiservice__http__0,
changeOrigin: true
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

The comment states the prefix 'api' is stripped, but no path rewrite is configured; the proxy forwards /api/* unchanged. Either adjust the comment to reflect behavior or add a rewrite: path => path.replace(/^/api/, '').

Suggested change
changeOrigin: true
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')

Copilot uses AI. Check for mistakes.
{weatherData.length > 0 && (
<div className="weather-grid">
{weatherData.map((forecast, index) => (
<article key={index} className="weather-card" aria-label={`Weather for ${formatDate(forecast.date)}`}>
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

Using the loop index as a React key can cause inefficient re-renders if the array changes; prefer a stable identifier such as forecast.date (e.g., key={forecast.date}).

Suggested change
<article key={index} className="weather-card" aria-label={`Weather for ${formatDate(forecast.date)}`}>
<article key={forecast.date} className="weather-card" aria-label={`Weather for ${formatDate(forecast.date)}`}>

Copilot uses AI. Check for mistakes.
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

[nitpick] lib is set higher (ES2023) than target (ES2022), which can surface types for features that downlevel target may not support at runtime; align target and lib (e.g., both ES2023) or lower lib to match target for consistency.

Suggested change
"lib": ["ES2023"],
"lib": ["ES2022"],

Copilot uses AI. Check for mistakes.
gap: 0.25rem;
border: 1px solid var(--weather-card-border);
margin: 0;
padding: 0.25rem;
Copy link

Copilot AI Oct 18, 2025

Choose a reason for hiding this comment

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

The padding property is duplicated (lines 297 and 301); remove the redundant declaration to reduce noise.

Suggested change
padding: 0.25rem;

Copilot uses AI. Check for mistakes.
Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
Copilot finished work on behalf of davidfowl October 18, 2025 07:15
Copilot AI requested a review from davidfowl October 18, 2025 07:15
@davidfowl
Copy link
Member

@copilot Fix the translations to match the english name of the tempalte

…late

Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Oct 18, 2025

@copilot Fix the translations to match the english name of the tempalte

Updated all 14 localization files to correctly describe the Python + JavaScript starter template instead of "empty app" in commit [hash].

Copilot finished work on behalf of davidfowl October 18, 2025 07:24
@davidfowl
Copy link
Member

Tested run and deploy.

@maddymontaquila and @DamianEdwards are going to follow up and clean up the wording and ux.

@davidfowl davidfowl merged commit f458c2c into main Oct 18, 2025
599 of 603 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the 13.0 milestone Oct 18, 2025
@eerhardt eerhardt deleted the copilot/create-aspire-py-starter-template branch October 20, 2025 14:34
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.

4 participants