Skip to content

Fix Python samples failing Azure deployment due to localhost binding#187

Open
Copilot wants to merge 2 commits intomainfrom
copilot/fix-a365-deploy-issue
Open

Fix Python samples failing Azure deployment due to localhost binding#187
Copilot wants to merge 2 commits intomainfrom
copilot/fix-a365-deploy-issue

Conversation

Copy link
Contributor

Copilot AI commented Jan 24, 2026

Python agent samples fail to start on Azure App Service with "site did not start within expected time" error. The servers bind to localhost instead of 0.0.0.0, preventing Azure's load balancer from reaching the health endpoint.

Changes

Added production environment detection to dynamically bind to correct host:

# Detect production environment (Azure App Service sets WEBSITE_SITE_NAME)
is_production = os.getenv("WEBSITE_SITE_NAME") is not None
host = "0.0.0.0" if is_production else "localhost"
run_app(app, host=host, port=port, handle_signals=True)

Files Modified

  • python/agent-framework/sample-agent/host_agent_server.py
  • python/claude/sample-agent/host_agent_server.py
  • python/openai/sample-agent/host_agent_server.py
  • python/crewai/sample_agent/host_agent_server.py

Follows existing pattern in python/google-adk/sample-agent/main.py which already implements this correctly.

Original prompt

This section details on the original issue you should resolve

<issue_title>"a365 deploy" failed in python/agent-framework sample because the site did not start within the expected time</issue_title>
<issue_description>Describe the bug
In the python/agent-framework sample, after successfully set up things by running:

  1. a365 config init
  2. a365 setup all
  3. a365 publish

The a365 deploy fails due to "[ERR] The deployment failed because the site did not start within the expected time."
a365.deploy.log:

[2026-01-22 10:06:42.435] [INF] Azure CLI is using 64-bit Python (optimal)
[2026-01-22 10:06:42.446] [INF] Validating Azure Web App exists...
[2026-01-22 10:06:51.014] [INF] Confirmed Azure Web App 'shileiagent0121-webapp' exists
[2026-01-22 10:06:51.019] [INF] Starting multi-platform deployment...
[2026-01-22 10:06:51.020] [INF] [1/7] Detecting environment...
[2026-01-22 10:06:51.021] [INF] Detecting platform in: D:\git\Agent365-Samples\python\agent-framework\sample-agent
[2026-01-22 10:06:51.025] [INF] Detected Python project
[2026-01-22 10:06:51.026] [INF] Detected platform: Python
[2026-01-22 10:06:51.027] [INF] [2/7] Getting appropriate builder for Python environment...
[2026-01-22 10:06:51.028] [INF] [3/7] Validating Python environment...
[2026-01-22 10:06:51.030] [INF] Validating Python environment...
[2026-01-22 10:06:52.350] [INF] Python version: Python 3.14.0
[2026-01-22 10:06:52.351] [INF] pip version: pip 25.2 from D:\git\Agent365-Samples\python\agent-framework\sample-agent\.venv\Lib\site-packages\pip (python 3.14)
[2026-01-22 10:06:52.352] [INF] [4/7] Building Python application...
[2026-01-22 10:06:52.354] [INF] Removing old publish directory...
[2026-01-22 10:06:52.422] [INF] Building Python project...
[2026-01-22 10:06:54.179] [INF] Copying project files...
[2026-01-22 10:06:54.653] [INF] No local packages found in publish/dist, running uv build in publish directory...
[2026-01-22 10:07:02.370] [INF] Successfully built 1 local packages in publish directory
[2026-01-22 10:07:02.373] [INF] Created requirements.txt for Azure deployment
[2026-01-22 10:07:02.376] [INF] Created .deployment file to force Oryx build
[2026-01-22 10:07:02.378] [INF] Copied .env.template file
[2026-01-22 10:07:02.379] [INF] Excluded .env file from deployment package for security
[2026-01-22 10:07:02.380] [INF] Environment variables should be set as Azure App Settings
[2026-01-22 10:07:02.381] [INF] Python project prepared for Azure deployment
[2026-01-22 10:07:02.382] [INF] Azure will handle dependency installation during deployment
[2026-01-22 10:07:02.383] [INF] Build output: D:\git\Agent365-Samples\python\agent-framework\sample-agent\publish
[2026-01-22 10:07:02.384] [INF] [5/7] Creating Oryx manifest...
[2026-01-22 10:07:02.387] [INF] Creating Oryx manifest for Python...
[2026-01-22 10:07:02.391] [INF] Created runtime.txt for Python version detection
[2026-01-22 10:07:02.459] [INF] Detected Python version: 3.14
[2026-01-22 10:07:02.481] [INF] Selected best Microsoft Agent 365 entry point: start_with_generic_host.py (priority: 45, hasMain: True)
[2026-01-22 10:07:02.488] [INF] Detected Microsoft Agent 365 entry point: start_with_generic_host.py, using command: python start_with_generic_host.py
[2026-01-22 10:07:02.492] [INF] Manifest command: python start_with_generic_host.py
[2026-01-22 10:07:02.493] [INF] [6/7] Converting .env to Azure App Settings...
[2026-01-22 10:07:02.498] [INF] Converting .env file to Azure App Settings...
[2026-01-22 10:07:02.504] [INF] Setting 27 environment variables as Azure App Settings...
[2026-01-22 10:07:10.980] [INF] Successfully converted 27 environment variables to Azure App Settings
[2026-01-22 10:07:10.981] [INF] [7/7] Setting Python startup command...
[2026-01-22 10:07:10.985] [INF] Selected best Microsoft Agent 365 entry point: start_with_generic_host.py (priority: 45, hasMain: True)
[2026-01-22 10:07:10.985] [INF] Detected Microsoft Agent 365 entry point: start_with_generic_host.py, using command: python start_with_generic_host.py
[2026-01-22 10:07:10.986] [INF] Setting Azure Web App startup command: python start_with_generic_host.py
[2026-01-22 10:07:19.918] [INF] Successfully set startup command for Azure Web App
[2026-01-22 10:07:19.919] [INF] Waiting for Azure configuration to stabilize...
[2026-01-22 10:07:24.943] [INF] [6/7] Creating deployment package: D:\git\Agent365-Samples\python\agent-framework\sample-agent\app.zip
[2026-01-22 10:07:24.954] [INF] Compressing 28 files from D:\git\Agent365-Samples\python\agent-framework\sample-agent\publish...
[2026-01-22 10:07:25.096] [INF] Package created in 0.1s - Size: 1.26 MB
[2026-01-22 10:07:25.099] [INF] [7/7] Deploying to Azure Web App...
[2026-01-22 10:07:25.099] [INF]   Resource Group: rg-lsl-agent365-eastus
[2026-01-22 10:07:25.100] [INF]   App Name: shileiagent0121-webapp
[2026-01-22 10:07:25.101] [INF] Deployment typically takes 2-5 minutes to complete
[2026-01-22 10:07:25.101] [INF] Monitor progre...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes microsoft/Agent365-Samples#186

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

Co-authored-by: joratz <43622754+joratz@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix a365 deploy failure in python/agent-framework sample Fix Python samples failing Azure deployment due to localhost binding Jan 24, 2026
Copilot AI requested a review from joratz January 24, 2026 01:52
@joratz joratz marked this pull request as ready for review January 24, 2026 02:03
@joratz joratz requested a review from a team as a code owner January 24, 2026 02:03
Copilot AI review requested due to automatic review settings January 24, 2026 02:03
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

This pull request fixes a critical deployment issue where Python agent samples fail to start on Azure App Service due to binding to localhost instead of 0.0.0.0. The fix adds production environment detection using the WEBSITE_SITE_NAME environment variable, which is automatically set by Azure App Service, to dynamically choose the appropriate host binding.

Changes:

  • Added production environment detection logic to four Python sample host servers
  • Modified server binding to use 0.0.0.0 in production (Azure) and localhost for local development
  • Updated startup messages to reflect the actual host being used

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
python/openai/sample-agent/host_agent_server.py Added WEBSITE_SITE_NAME detection and dynamic host binding for production vs development
python/crewai/sample_agent/host_agent_server.py Added WEBSITE_SITE_NAME detection and dynamic host binding for production vs development
python/claude/sample-agent/host_agent_server.py Added WEBSITE_SITE_NAME detection and dynamic host binding for production vs development
python/agent-framework/sample-agent/host_agent_server.py Added WEBSITE_SITE_NAME detection and dynamic host binding for production vs development

Comment on lines 314 to 315
print(f"📚 Bot Framework endpoint: http://localhost:{port}/api/messages")
print(f"❤️ Health: http://localhost:{port}/api/health")
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

The endpoint URLs in the print statements still show "http://localhost:{port}" even when the server is bound to "0.0.0.0" in production. In production environments, these URLs won't accurately reflect how the service is accessed. Consider either using the actual host variable in the URLs or adding a clarifying comment that these are example local URLs for development reference only.

Suggested change
print(f"📚 Bot Framework endpoint: http://localhost:{port}/api/messages")
print(f"❤️ Health: http://localhost:{port}/api/health")
print(f"📚 Bot Framework endpoint: http://{host}:{port}/api/messages")
print(f"❤️ Health: http://{host}:{port}/api/health")

Copilot uses AI. Check for mistakes.
Comment on lines 331 to 332
print(f"Bot Framework endpoint: http://localhost:{port}/api/messages")
print(f"Health: http://localhost:{port}/api/health")
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

The endpoint URLs in the print statements still show "http://localhost:{port}" even when the server is bound to "0.0.0.0" in production. In production environments, these URLs won't accurately reflect how the service is accessed. Consider either using the actual host variable in the URLs or adding a clarifying comment that these are example local URLs for development reference only.

Suggested change
print(f"Bot Framework endpoint: http://localhost:{port}/api/messages")
print(f"Health: http://localhost:{port}/api/health")
print(f"Bot Framework endpoint: http://{host}:{port}/api/messages")
print(f"Health: http://{host}:{port}/api/health")
if is_production:
print(
"Note: In production, replace '0.0.0.0' with the externally accessible host name or IP."
)

Copilot uses AI. Check for mistakes.
Comment on lines 450 to 451
print(f"📚 Bot Framework endpoint: http://localhost:{port}/api/messages")
print(f"❤️ Health: http://localhost:{port}/api/health")
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

The endpoint URLs in the print statements still show "http://localhost:{port}" even when the server is bound to "0.0.0.0" in production. In production environments, these URLs won't accurately reflect how the service is accessed. Consider either using the actual host variable in the URLs or adding a clarifying comment that these are example local URLs for development reference only.

Suggested change
print(f"📚 Bot Framework endpoint: http://localhost:{port}/api/messages")
print(f"❤️ Health: http://localhost:{port}/api/health")
print(f"📚 Bot Framework endpoint: http://{host}:{port}/api/messages")
print(f"❤️ Health: http://{host}:{port}/api/health")

Copilot uses AI. Check for mistakes.
Comment on lines 318 to 319
print(f"📚 Endpoint: http://localhost:{port}/api/messages")
print(f"❤️ Health: http://localhost:{port}/api/health\n")
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

The endpoint URLs in the print statements still show "http://localhost:{port}" even when the server is bound to "0.0.0.0" in production. In production environments, these URLs won't accurately reflect how the service is accessed. Consider either using the actual host variable in the URLs or adding a clarifying comment that these are example local URLs for development reference only.

Copilot uses AI. Check for mistakes.
port = desired_port + 1

# Detect production environment (Azure App Service sets WEBSITE_SITE_NAME)
is_production = os.getenv("WEBSITE_SITE_NAME") is not None
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we even need this variable? We should judge if the app is in prod vs dev based on environment variable like "ENVIRONMENT" or "ASP_ENVIRONMENT" or port number, not based on website name. I think this website name itself is causing a lot of confusion and we cannot set it prod vs development in E2E. Let me know if you think otherwise


# Detect production environment (Azure App Service sets WEBSITE_SITE_NAME)
is_production = os.getenv("WEBSITE_SITE_NAME") is not None
host = "0.0.0.0" if is_production else "localhost"
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should decide if it's prod vs local based on ip address, not the otherway around, no?

@pontemonti
Copy link
Contributor

🤖 Claude Code Review Summary

Review Date: 2026-01-24T23:06:01Z
Approval Status: APPROVED WITH MINOR NOTES

Findings Summary

Severity Count
Critical 0
High 0
Medium 4
Low 0

Findings

ID Title File
CRM-001 Inconsistent Log Output - Endpoint URLs Still Show localhost python/agent-framework/sample-agent/host_agent_server.py
CRM-002 Inconsistent Log Output - claude sample python/claude/sample-agent/host_agent_server.py
CRM-003 Inconsistent Log Output - crewai sample python/crewai/sample_agent/host_agent_server.py
CRM-004 Inconsistent Log Output - openai sample python/openai/sample-agent/host_agent_server.py

Overall Assessment

The core fix is correct, security-compliant, and follows established patterns. The medium-priority log message inconsistencies are cosmetic and match the reference implementation's behavior (python/google-adk/sample-agent/main.py).

The PR successfully addresses a real Azure deployment blocker with minimal risk.


Review generated by Claude Code

print(f"🔒 Auth: {'Enabled' if auth_configuration else 'Anonymous'}")
print(f"🚀 Server: localhost:{port}")
print(f"🚀 Server: {host}:{port}")
print(f"📚 Endpoint: http://localhost:{port}/api/messages")
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 [CRM-001] Inconsistent Log Output

The print statements for Endpoint and Health URLs still display http://localhost:{port} even when the server binds to 0.0.0.0 in production. This creates misleading log output for operators monitoring Azure deployments.

Suggestion: Update to use {host} for consistency, or clarify these are local reference URLs. Note: This matches the reference implementation (Google ADK) behavior, so it's acceptable but could be improved.

print(f"⚠️ Requested port {desired_port} busy; using fallback {port}")
print(f"\n🚀 Starting server on localhost:{port}")
print(f"\n🚀 Starting server on {host}:{port}")
print(f"📚 Bot Framework endpoint: http://localhost:{port}/api/messages")
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 [CRM-002] Inconsistent Log Output

Same issue as CRM-001 - endpoint and health URLs still reference localhost even when binding to 0.0.0.0.

Suggestion: Update for consistency with actual host binding.

print(f"Requested port {desired_port} busy; using fallback {port}")
print(f"\nStarting server on localhost:{port}")
print(f"\nStarting server on {host}:{port}")
print(f"Bot Framework endpoint: http://localhost:{port}/api/messages")
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 [CRM-003] Inconsistent Log Output

Same issue as CRM-001 - endpoint and health URLs still reference localhost even when binding to 0.0.0.0.

Suggestion: Update for consistency with actual host binding.

@@ -306,13 +310,13 @@ async def anonymous_claims(request, handler):
print("🎯 Compatible with Agents Playground")
if port != desired_port:
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 [CRM-004] Inconsistent Log Output

Same issue as CRM-001 - endpoint and health URLs still reference localhost even when binding to 0.0.0.0.

Suggestion: Update for consistency with actual host binding.

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