Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python Agent on Azure Container Apps

This project deploys the FastAPI container to Azure Container Apps using Bicep. The API exposes /health and /forecast; /forecast calls the URL in BACKEND_API_BASE.

Application Insights is connected to the existing Log Analytics workspace. Container Apps platform logs, application logs, request traces, and requests dependency spans are available through Azure Monitor.

Application endpoints require an API key in the x-api-key header. The /health endpoint remains unauthenticated for platform probes.

Design

flowchart LR
  subgraph Local[Developer machine]
    Copilot[VS Code Copilot]
    MCP[mcp_server.py<br/>MCP stdio server]
    Config[.vscode/mcp.json<br/>AGENT_API_BASE_URL<br/>AGENT_API_KEY]
    Copilot -->|MCP tools| MCP
    Config -. configures .-> MCP
  end

  subgraph Azure[Azure]
    ACR[Azure Container Registry<br/>python-agent image]
    subgraph ACA[Azure Container Apps]
      App[python-agent-app<br/>FastAPI + Uvicorn :8000]
      Env[Managed environment<br/>1-3 replicas]
      App -. runs in .-> Env
    end
    Insights[Application Insights]
    Logs[Log Analytics workspace]
    ACR -->|image pull| App
    App -->|telemetry and stdout logs| Insights
    Env -->|platform and app logs| Logs
    Insights -->|workspace-backed| Logs
  end

  Deploy[deploy.ps1] -->|docker buildx build --push| ACR
  Deploy -->|Bicep deployment| ACA
  MCP -->|HTTPS + x-api-key| App
  Client[API clients / probes] -->|HTTPS| App
  Forecast[Open-Meteo or configured backend<br/>BACKEND_API_BASE] <-->|GET /forecast| App
Loading

Request flow

sequenceDiagram
  participant C as Client or MCP tool
  participant A as FastAPI app
  participant B as Forecast backend
  participant O as Azure Monitor

  C->>A: GET /health or /forecast<br/>optional x-request-id
  A->>A: Skip auth for /health<br/>otherwise compare x-api-key
  alt Protected request has a valid key
    A->>B: GET /forecast\nlatitude, longitude, current
    B-->>A: Forecast JSON
    A-->>C: 200 JSON + x-request-id
  else Missing or invalid key
    A-->>C: 401 Invalid or missing API key
  end
  A-)O: Structured request logs, traces, dependency spans
Loading

Component map

Component Responsibility Configuration boundary
main.py FastAPI routes, API-key middleware, request IDs, backend call, telemetry API_KEY, BACKEND_API_BASE, REQUEST_TIMEOUT_SECONDS
mcp_server.py Exposes health_check and get_forecast as MCP tools over stdio AGENT_API_BASE_URL, AGENT_API_KEY
Dockerfile Builds the production API image and starts Uvicorn on port 8000 requirements.txt
deploy.ps1 Builds and pushes the image, then deploys the Bicep template Azure resource names, image tag, API key
infra/main.bicep Defines Container Apps, registry access, secrets, scaling, and monitoring Bicep parameters

Prerequisites

  • Azure CLI logged in with access to the target subscription
  • Docker Desktop running with buildx support
  • Existing Azure resources:
    • Resource group: python-agent-rg-eastus
    • Azure Container Registry: pythonagentacr
    • Log Analytics workspace: workspace-pythonagent-eastus
    • Container Apps environment: python-agent-env

The ACR must have admin credentials enabled because the Bicep template uses its registry credentials for image pulls.

Deploy

From this directory, run:

.\deploy.ps1

The script securely prompts for the API key when -ApiKey is omitted. Do not commit the key or place it in infra/main.parameters.json.

The script builds and pushes a linux/amd64 image, then applies infra/main.bicep to the East US resource group.

To use a different backend API or image tag:

.\deploy.ps1 -BackendApiBase 'https://example.internal/api' -ImageTag 'v2'

Call the protected API with:

curl.exe -H "x-api-key: YOUR_API_KEY" "https://python-agent-app.calmcliff-2f307d44.eastus.azurecontainerapps.io/forecast?lat=52.52&lon=13.41"

Preview changes

az deployment group what-if `
  --resource-group python-agent-rg-eastus `
  --template-file infra/main.bicep `
  --parameters @infra/main.parameters.json apiKey='preview-only'

The deployment outputs the public Container App URL as containerAppUrl.

GitHub Actions

The workflow at .github/workflows/deploy-container-app.yml builds and pushes a linux/amd64 image tagged with the commit SHA, then runs az containerapp update.

Configure these GitHub Actions secrets:

  • AZURE_CLIENT_ID: Entra application or user-assigned managed identity client ID
  • AZURE_TENANT_ID: Entra tenant ID
  • AZURE_SUBSCRIPTION_ID: Azure subscription ID

Configure a federated GitHub credential for the Azure identity with issuer https://token.actions.githubusercontent.com, subject repo:OWNER/REPOSITORY:ref:refs/heads/main, and audience api://AzureADTokenExchange. Grant the identity AcrPush on pythonagentacr and Contributor on python-agent-app or the python-agent-rg-eastus resource group.

After pushing to main, the workflow updates the app to the image tagged with that commit SHA. It does not change the existing API-key secret; authentication remains managed by the Container App configuration.

Observability

The API writes structured request logs to stdout, including status, duration, and request ID. It also records backend dependency requests and propagates an x-request-id response header. Configure verbosity or backend timeout when needed:

.\deploy.ps1

Use Log Analytics with the Container App's environment logs, and use Application Insights transaction search and the Application Map for request and dependency telemetry.

VS Code Copilot MCP

The workspace file .vscode/mcp.json configures Copilot to launch mcp_server.py over stdio. The bridge calls the deployed FastAPI URL and prompts for the protected API key without storing it in the repository. Start or refresh the fastapi-agent MCP server from VS Code's MCP controls, then approve the prompt for the API key.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages