-
Notifications
You must be signed in to change notification settings - Fork 720
Add aspire-py-starter template for Python and JavaScript applications #12136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
src/Aspire.ProjectTemplates/templates/aspire-py-starter/9.5/apphost.cs
Outdated
Show resolved
Hide resolved
…e 13.0 Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
|
@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. |
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 12136Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 12136" |
1 similar comment
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 12136Or
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"> |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
| "aspire-13.0-tfms": "net8.0;net9.0;net10.0" | ||
| }, | ||
| "precedence": "9000", | ||
| "identity": "Aspire.PyStarter.CSharp.8.0", |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| "type": "solution", | ||
| "editorTreatAs": "solution", |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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+.
| "skipRestore": { | ||
| "type": "parameter", | ||
| "datatype": "bool", | ||
| "description": "If specified, skips the automatic restore of the project on create.", | ||
| "defaultValue": "false" | ||
| } |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!! | |||
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
… 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>
Updated DotnetTemplateFactory to include aspire-py-starter template (gated by SingleFileAppHostEnabled feature) in commit 4e89b52. |
There was a problem hiding this 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 |
Copilot
AI
Oct 18, 2025
There was a problem hiding this comment.
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.
| COPY --from=frontend-stage /dist /app/static | |
| COPY --from=frontend-stage /frontend/dist /app/static |
| // 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 |
Copilot
AI
Oct 18, 2025
There was a problem hiding this comment.
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/, '').
| changeOrigin: true | |
| changeOrigin: true, | |
| rewrite: (path) => path.replace(/^\/api/, '') |
| {weatherData.length > 0 && ( | ||
| <div className="weather-grid"> | ||
| {weatherData.map((forecast, index) => ( | ||
| <article key={index} className="weather-card" aria-label={`Weather for ${formatDate(forecast.date)}`}> |
Copilot
AI
Oct 18, 2025
There was a problem hiding this comment.
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}).
| <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)}`}> |
| "compilerOptions": { | ||
| "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", | ||
| "target": "ES2022", | ||
| "lib": ["ES2023"], |
Copilot
AI
Oct 18, 2025
There was a problem hiding this comment.
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.
| "lib": ["ES2023"], | |
| "lib": ["ES2022"], |
| gap: 0.25rem; | ||
| border: 1px solid var(--weather-card-border); | ||
| margin: 0; | ||
| padding: 0.25rem; |
Copilot
AI
Oct 18, 2025
There was a problem hiding this comment.
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.
| padding: 0.25rem; |
...ojectTemplates/templates/aspire-py-starter/.template.config/localize/templatestrings.it.json
Outdated
Show resolved
Hide resolved
...ojectTemplates/templates/aspire-py-starter/.template.config/localize/templatestrings.fr.json
Outdated
Show resolved
Hide resolved
...ojectTemplates/templates/aspire-py-starter/.template.config/localize/templatestrings.es.json
Outdated
Show resolved
Hide resolved
...ojectTemplates/templates/aspire-py-starter/.template.config/localize/templatestrings.de.json
Outdated
Show resolved
Hide resolved
...ojectTemplates/templates/aspire-py-starter/.template.config/localize/templatestrings.cs.json
Outdated
Show resolved
Hide resolved
src/Aspire.ProjectTemplates/templates/aspire-py-starter/.template.config/template.json
Show resolved
Hide resolved
Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
|
@copilot Fix the translations to match the english name of the tempalte |
…late Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
Updated all 14 localization files to correctly describe the Python + JavaScript starter template instead of "empty app" in commit [hash]. |
|
Tested run and deploy. @maddymontaquila and @DamianEdwards are going to follow up and clean up the wording and ux. |
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:
This addresses feedback from @davidfowl to fix the translations to match the English template description.
Original prompt
This pull request was created as a result of the following prompt from Copilot chat.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.