{"id":201,"date":"2025-12-08T08:00:00","date_gmt":"2025-12-08T16:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/aspire\/?p=201"},"modified":"2026-01-08T07:19:44","modified_gmt":"2026-01-08T15:19:44","slug":"python-is-first-class-in-aspire-13","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/aspire\/python-is-first-class-in-aspire-13\/","title":{"rendered":"Python is First Class in Aspire 13"},"content":{"rendered":"<p>With the release of Aspire 13, Python has been elevated to a first-class citizen alongside .NET and JavaScript, transforming Aspire into a truly polyglot application platform. The new <code>Aspire.Hosting.Python<\/code> package provides comprehensive support for developing, debugging, and deploying Python applications within distributed systems, whether you&#8217;re building microservices with FastAPI, data processing pipelines, or machine learning workloads.<\/p>\n<h2>Adding Python Applications to Aspire<\/h2>\n<p>Aspire 13 offers three flexible ways to run Python code, each designed for specific use cases:<\/p>\n<h3>Python Scripts<\/h3>\n<p>Use <code>AddPythonApp()<\/code> to execute Python script files directly:<\/p>\n<pre><code class=\"language-csharp\">var builder = DistributedApplication.CreateBuilder(args);\n\nvar scriptApp = builder.AddPythonApp(\"data-processor\",\n    appDirectory: \"..\/scripts\",\n    scriptPath: \"process_data.py\");<\/code><\/pre>\n<p>This is perfect for standalone Python scripts that process data, perform batch operations, or run background tasks.<\/p>\n<h3>Python Modules<\/h3>\n<p>Use <code>AddPythonModule()<\/code> to run Python modules using the <code>python -m<\/code> pattern. This is ideal for running Python packages:<\/p>\n<pre><code class=\"language-csharp\">var pythonModule = builder.AddPythonModule(\"ml-service\",\n    appDirectory: \"..\/ml-service\",\n    module: \"inference.server\");<\/code><\/pre>\n<h3>Python Executables<\/h3>\n<p>Use <code>AddPythonExecutable()<\/code> to launch executables from virtual environments or Python-based command-line tools:<\/p>\n<pre><code class=\"language-csharp\">var pythonApp = builder.AddPythonExecutable(\"cli-tool\",\n    appDirectory: \"..\/tools\",\n    executableName: \"mytool\");<\/code><\/pre>\n<h3>ASGI Web Applications with Uvicorn<\/h3>\n<p>For modern Python web applications using FastAPI, Starlette, or Quart, use <code>AddUvicornApp()<\/code>:<\/p>\n<pre><code class=\"language-csharp\">var api = builder.AddUvicornApp(\"fastapi-service\", \"..\/python-api\", \"main:app\")\n    .WithExternalHttpEndpoints()\n    .WithHttpHealthCheck(\"\/health\");<\/code><\/pre>\n<p>This method provides several powerful features automatically:<\/p>\n<ul>\n<li>Configures HTTP endpoints for service discovery<\/li>\n<li>Sets up appropriate Uvicorn command-line arguments<\/li>\n<li>Supports hot-reload during development for rapid iteration<\/li>\n<li>Integrates with Aspire&#8217;s health check system to monitor application health<\/li>\n<\/ul>\n<h2>Virtual Environment Support<\/h2>\n<p>Python applications typically use virtual environments to manage dependencies. Aspire automatically manages virtual environments when you add a Python resource with a <code>requirements.txt<\/code> or <code>pyproject.toml<\/code> file. By default, <code>python -m venv<\/code> is called to create a virtual environment in the <code>.venv<\/code> folder. You can customize where the virtual environment directory is created with the <code>WithVirtualEnvironment()<\/code> method:<\/p>\n<pre><code class=\"language-csharp\">var pythonApp = builder.AddPythonModule(\"ml-service\", \"..\/ml-service\", \"inference\")\n    .WithVirtualEnvironment(\"myenv\", createIfNotExists: true);<\/code><\/pre>\n<p>You can control whether the virtual environment should be automatically created if it doesn&#8217;t exist, ensuring a consistent development and deployment experience across your team.<\/p>\n<h2>Package Management<\/h2>\n<p>Aspire 13 supports flexible, auto-detected package management with both traditional and modern Python package managers. The system automatically detects and configures package management when you add a Python application, requiring minimal manual configuration.<\/p>\n<h3>Using uv (Recommended)<\/h3>\n<p>uv is a modern, high-performance Python package manager that offers significant speed improvements over traditional tools:<\/p>\n<pre><code class=\"language-csharp\">var pythonApp = builder.AddPythonApp(\"data-processor\", \".\/scripts\", \"process_data.py\")\n    .WithUv();<\/code><\/pre>\n<p>Calling <code>.WithUv()<\/code> will ensure that <code>uv sync<\/code> is executed before your application is started, ensuring any dependencies are installed and up to date in the project\u2019s virtual environment before the app runs.<\/p>\n<h3>Using pip<\/h3>\n<p>For projects using traditional pip-based workflows. By default, <code>pip install -r requirements.txt<\/code> is executed when a <code>requirements.txt<\/code> file is detected. You can pass customized arguments by calling <code>.WithPip<\/code>:<\/p>\n<pre><code class=\"language-csharp\">var pythonApp = builder.AddPythonApp(\"data-processor\", \".\/scripts\", \"process_data.py\")\n    .WithPip(installArgs: [\"--cache-dir\", \"my-cache\"]);<\/code><\/pre>\n<p>Aspire also supports standard Python venv for virtual environment creation and management, giving you the flexibility to use the tools your team prefers.<\/p>\n<h2>Development Experience<\/h2>\n<h3>VS Code Debugging<\/h3>\n<p>Python applications in Aspire support full breakpoint debugging in Visual Studio Code with no additional configuration required. The <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=microsoft-aspire.aspire-vscode\">Aspire VS Code extension<\/a> automatically recognizes the <a href=\"https:\/\/code.visualstudio.com\/docs\/python\/debugging\">Python Debugger VS Code extension<\/a> and generates launch configurations for your Python services. Simply set breakpoints in your Python code and start debugging.<\/p>\n<p>Aspire configures the Python runtime for debugging, allowing you to step through your code, inspect variables, and diagnose issues just as easily as you would with .NET applications.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/aspire\/wp-content\/uploads\/sites\/90\/2026\/01\/debugging.webp\" alt=\"Debugging a Python application with Visual Studio Code Aspire extension\" \/><\/p>\n<h3>Certificate Trust for Local Development<\/h3>\n<p>Aspire automatically configures a developer certificate for you and trusts it for Python applications through environment variables like <code>SSL_CERT_FILE<\/code> and <code>REQUESTS_CA_BUNDLE<\/code>. This enables secure HTTPS connections during local development without manual certificate configuration, making it seamless to test secure communication between services.<\/p>\n<h2>Service Discovery and Integration<\/h2>\n<p>Python applications registered with Aspire automatically participate in service discovery. When you reference a service, Aspire provides simplified environment variables:<\/p>\n<pre><code class=\"language-csharp\">var service1 = builder.AddUvicornApp(\"service1\", \"..\/service1\", \"main:app\");\n\nvar service2 = builder.AddUvicornApp(\"service2\", \"..\/service2\", \"main:app\")\n    .WithReference(service1);<\/code><\/pre>\n<p>Python applications receive environment variables like <code>SERVICE1_HTTP<\/code> and <code>SERVICE1_HTTPS<\/code> instead of complex service discovery formats. This makes service location simple and accessible:<\/p>\n<pre><code class=\"language-python\">import os\nimport httpx\n\n# Easy access to referenced services\nservice1_url = os.environ[\"SERVICE1_HTTP\"]\nresponse = httpx.get(f\"{service1_url}\/health\")<\/code><\/pre>\n<h2>Polyglot Database Connections<\/h2>\n<p>When working with databases, Aspire automatically exposes connection information in multiple formats to accommodate different Python libraries and conventions:<\/p>\n<pre><code class=\"language-csharp\">var postgres = builder.AddPostgres(\"postgres\")\n    .AddDatabase(\"appdb\");\n\nvar pythonService = builder.AddPythonModule(\"data-service\", \"..\/service\", \"app\")\n    .WithReference(postgres);<\/code><\/pre>\n<p>Your Python application receives both URI format and individual connection properties:<\/p>\n<pre><code class=\"language-python\">import os\nimport asyncpg\n\n# Option 1: Use URI format (e.g., for SQLAlchemy)\ndatabase_url = os.environ[\"APPDB_URI\"]  # postgresql:\/\/user:pass@host:port\/dbname\ndb_pool = await asyncpg.create_pool(database_url)\n\n# Option 2: Use individual properties\ndb_pool = await asyncpg.create_pool(\n    host=os.environ[\"APPDB_HOST\"],\n    port=os.environ[\"APPDB_PORT\"],\n    user=os.environ[\"APPDB_USERNAME\"],\n    password=os.environ[\"APPDB_PASSWORD\"],\n    database=os.environ[\"APPDB_DATABASE\"]\n)<\/code><\/pre>\n<p>This flexibility ensures you can use your preferred Python database library without adapting to Aspire-specific connection patterns.<\/p>\n<h2>Production Deployment<\/h2>\n<p>Aspire takes the complexity out of deploying Python applications to production. When you publish your Aspire project, the system automatically generates production-ready Dockerfiles for your Python applications. These Dockerfiles are intelligently adapted based on:<\/p>\n<ul>\n<li>Your chosen package manager (uv or pip)<\/li>\n<li>Python version detection from <code>.python-version<\/code>, <code>pyproject.toml<\/code>, or your virtual environment<\/li>\n<li>Your application&#8217;s dependency requirements<\/li>\n<\/ul>\n<p>This means you get optimized container images without writing Docker configuration manually. The generated Dockerfiles follow best practices for security and performance, ensuring your Python applications are production-ready.<\/p>\n<h2>Getting Started with the Aspire Python Starter Template<\/h2>\n<p>Want to jump right in? The new <code>aspire-py-starter<\/code> template provides a complete full-stack application demonstrating Python&#8217;s integration with Aspire:<\/p>\n<pre><code class=\"language-bash\">aspire new aspire-py-starter<\/code><\/pre>\n<p>The starter template includes:<\/p>\n<ul>\n<li><strong>FastAPI backend<\/strong> &#8211; A modern, fast Python web framework<\/li>\n<li><strong>Vite + React frontend<\/strong> &#8211; A responsive single-page application<\/li>\n<li><strong>OpenTelemetry integration<\/strong> &#8211; Built-in distributed tracing and metrics<\/li>\n<li><strong>Redis caching<\/strong> &#8211; Demonstrates integration with Aspire&#8217;s Redis support<\/li>\n<li><strong>Container files<\/strong> &#8211; Ready-to-deploy Docker container containing both the backend and frontend<\/li>\n<\/ul>\n<p>This template is the perfect starting point for understanding how Python applications work within Aspire&#8217;s ecosystem.<\/p>\n<h2>Summary<\/h2>\n<p>Aspire 13 marks a significant milestone in cloud-native development by elevating Python to a first-class citizen alongside .NET and JavaScript. This transformation demonstrates Aspire&#8217;s evolution into a truly polyglot application platform.<\/p>\n<p>Python developers now enjoy a deep,  first-class Aspire integration, including:<\/p>\n<ul>\n<li>Multiple flexible ways to run Python code (scripts, modules, executables, and ASGI apps)<\/li>\n<li>Automatic package management with uv and pip support<\/li>\n<li>Full debugging support in VS Code with zero configuration<\/li>\n<li>Simplified service discovery with intuitive environment variables<\/li>\n<li>Polyglot database connection formats compatible with popular Python libraries<\/li>\n<li>Automatic production-ready Dockerfile generation<\/li>\n<li>Built-in OpenTelemetry integration for observability<\/li>\n<\/ul>\n<p>Whether you&#8217;re building microservices with FastAPI, data processing pipelines, machine learning inference services, or full-stack applications, Aspire provides a consistent, productive development experience from local development to production deployment.<\/p>\n<p>Get started today by trying the <code>aspire-py-starter<\/code> template or add the <code>Aspire.Hosting.Python<\/code> NuGet package to your existing app host project. For more details, check out the <a href=\"https:\/\/aspire.dev\/integrations\/frameworks\/python\">Python support documentation on aspire.dev<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aspire 13 introduces first-class Python support with dedicated APIs for hosting Python applications, modules, and ASGI web apps alongside your .NET services.<\/p>\n","protected":false},"author":112653,"featured_media":256,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,17,19],"tags":[25,6,24],"class_list":["post-201","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspire-category","category-deep-dives","category-integrations","tag-net","tag-aspire-13","tag-python"],"acf":[],"blog_post_summary":"<p>Aspire 13 introduces first-class Python support with dedicated APIs for hosting Python applications, modules, and ASGI web apps alongside your .NET services.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts\/201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/users\/112653"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/comments?post=201"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/posts\/201\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/media\/256"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/media?parent=201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/categories?post=201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/aspire\/wp-json\/wp\/v2\/tags?post=201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}