Bemærk
Adgang til denne side kræver godkendelse. Du kan prøve at logge på eller ændre mapper.
Adgang til denne side kræver godkendelse. Du kan prøve at ændre mapper.
This article shows you how to deploy a Hosted agent in Foundry Agent Service from Python or .NET source code, without building or pushing a container image. You upload a .zip of your code (and optionally your dependencies), and Agent Service either runs it as-is or builds your dependencies for you in the cloud.
Tip
For most scenarios, deploy with the Azure Developer CLI (azd) or the Foundry Toolkit for VS Code. These tools do the heavy lifting for you: they package your source, upload it, poll for active, and configure role-based access control automatically. To get started, follow the Quickstart: Deploy your first hosted agent and choose Code (or Source Code (ZIP upload)) when prompted for a deployment method.
Use the SDK and REST procedures in this article when you need to deploy source-code agents programmatically—from the Python SDK or .NET SDK in your own applications, or directly over the REST API for custom tooling, language-agnostic automation, or integration with existing continuous-delivery systems. In this article, you complete the following tasks:
- Pick a dependency-resolution mode and package your source.
- Create the agent, wait for it to reach
active, and invoke it. - Update, version, download, and stream logs for the deployed agent.
If you need full control of the runtime image or you already have a working Dockerfile, use the container-based path: Deploy a hosted agent.
Important
Source-code deployment for Hosted agents is in preview. Functionality, region availability, and APIs might change before general availability.
Prerequisites
- A Microsoft Foundry project in a supported region.
- Azure CLI version 2.80 or later, signed in to the tenant that owns the project.
pipfrom Python 3.13 or later, to package your source locally.The
azure-ai-projectsversion 2.2.0 or later andazure-identitypackages.pip install "azure-ai-projects>=2.2.0" azure-identity
Supported runtimes
The code_configuration.runtime field in the agent definition accepts the following values. Pick the runtime that matches the binaries in your zip—Linux x86_64 wheels for Python, or the TargetFramework of your dotnet publish output for .NET.
| Language | Runtime values |
|---|---|
| Python | python_3_13, python_3_14 |
| .NET | dotnet_10 |
Language version support policy
The Agent Service runtime includes the platform-built container image for each value of code_configuration.runtime. To keep your deployed agents fully supported, Foundry aligns hosted agent language support with end-of-life support for each language. Support ends on the community end-of-support date for the language version. Microsoft might retire a code_configuration.runtime value earlier when platform constraints (such as the underlying base image) require it.
For upstream end-of-support schedules, see:
- Python: Status of Python versions (python.org).
- .NET: .NET and .NET Core support policy.
Retirement phase
After a language end-of-life date, you can still create, update, and run hosted agents that use the retired runtime value. However, those agents aren't eligible for support, new features, or security patches until you upgrade them to a supported runtime by setting a current code_configuration.runtime value and redeploying.
Required permissions
You need Foundry Project Manager at project scope to deploy a Hosted agent. This role grants the data-plane permissions to create and update agents, plus the ability to assign Foundry User to the platform-created agent identity that your running code uses to call models and tools.
Your agent runs as a platform-assigned managed identity that's separate from your user identity. That identity needs Foundry User to call models from inside the container. If you deploy with azd or the Foundry Toolkit for Visual Code, the tooling assigns this role automatically. If you deploy with REST, grant it yourself—see Hosted agent permissions reference.
For REST calls, include the preview feature header on mutating requests (Create, Update, Delete) while the feature is in preview:
Foundry-Features: CodeAgents=V1Preview,HostedAgents=V1Preview
GET requests work without it today, but include it on every call to be safe—the header gates preview behavior and might be enforced more strictly before GA.
Deployment lifecycle
Every source-code deployment follows the same sequence: package → create or update → poll until active → invoke. The source-code path uses code_configuration in the agent definition; the image-based path uses container_configuration instead—the two are mutually exclusive on a single version.
Choose the path that fits your workflow. If you're not sure, start with the Azure Developer CLI or VS Code—it's the recommended path for most customers.
| Path | Best for | Packaging |
|---|---|---|
| Azure Developer CLI or VS Code | Most deployments, including first deployments and the fastest inner loop. | Tooling builds and uploads the zip for you. |
| Python SDK | Programmatic deployment from Python apps or automation. | You build the zip; the SDK uploads it. |
| .NET SDK | Programmatic deployment from .NET apps or automation. | The SDK zips a folder for you. |
| REST API | Custom tooling, language-agnostic automation, and CD systems. | You build the zip and send the multipart request. |
Choose how dependencies are resolved
Before you start, pick a value for code_configuration.dependency_resolution. This choice affects what you put in the zip.
| Value | Behavior | Use when |
|---|---|---|
remote_build |
Agent Service installs dependencies from requirements.txt (Python) or restores the project file (.NET) during provisioning. |
You want a small upload and the simplest inner loop. Recommended for first-time users. |
bundled |
The zip is run as-is. You ship prebuilt Linux dependencies in packages/ (Python) or dotnet publish output (.NET). |
You need reproducible builds, your dependencies are private or wheels-only, or your project doesn't restore cleanly server-side. |
For bundled mode, see Package the zip manually for the local build commands.
Deploy using the Azure Developer CLI or VS Code
The Azure Developer CLI (azd) and the Foundry Toolkit for VS Code automate the full source-code deployment lifecycle—they package your source into a zip, compute the SHA-256, upload it, poll for active, and configure role-based access control for you. These tools are the recommended path for most customers, and the fastest inner loop.
For a step-by-step walkthrough, see the Quickstart: Deploy your first hosted agent. Choose Code (or Source Code (ZIP upload)) when the quickstart asks for a deployment method.
Select source-code deployment
When you run azd ai agent init interactively, the tool prompts you to choose a deployment mode. Choose code to deploy from source as a ZIP upload instead of building a container image. The Foundry Toolkit for VS Code prompts you for the deployment method in the same way.
To select source-code deployment non-interactively—for example, in a CI/CD pipeline—pass --deploy-mode code. This mode requires --runtime and --entry-point, and accepts an optional --dep-resolution value of remote_build (default) or bundled:
azd ai agent init --no-prompt --project-id "<project-resource-id>" \
--deploy-mode code --runtime python_3_13 --entry-point main.py
With --no-prompt, the deployment mode defaults to container, so pass --deploy-mode code explicitly for source-code deployments. After initialization, run azd up to provision and deploy.
Use the SDK or REST paths in the following sections when you need to deploy programmatically from your own application or integrate with existing tooling.
Deploy from source code
Select your language or interface. Each tab walks through the same lifecycle: create the agent, poll until it reaches active, invoke it, and download the deployed code.
Use the Python SDK to deploy source-code agents from your own applications or automation. You build the zip yourself and pass its bytes and SHA-256 to the SDK, which uploads it and exposes the same create, poll, invoke, and download operations as the REST API. Code-deployment requires azure-ai-projects version 2.2.0 or later.
Source-code deployment uses the preview beta client surface, so create the client with allow_preview=True.
Build the zip
The Python SDK uploads a zip that you build. Use the same layout and dependency-resolution rules described in Package the zip manually. The minimal remote_build payload is a flat zip with main.py and requirements.txt at the root.
Create the agent
import hashlib
from pathlib import Path
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
CodeConfiguration,
CreateAgentVersionFromCodeContent,
CreateAgentVersionFromCodeMetadata,
HostedAgentDefinition,
ProtocolVersionRecord,
)
from azure.identity import DefaultAzureCredential
# Format: "https://<account>.services.ai.azure.com/api/projects/<project>"
PROJECT_ENDPOINT = "your_project_endpoint"
AGENT_NAME = "my-code-agent"
ZIP_PATH = Path("agent-code.zip")
code_zip_bytes = ZIP_PATH.read_bytes()
code_zip_sha256 = hashlib.sha256(code_zip_bytes).hexdigest()
credential = DefaultAzureCredential()
project = AIProjectClient(
endpoint=PROJECT_ENDPOINT,
credential=credential,
allow_preview=True,
)
content = CreateAgentVersionFromCodeContent(
metadata=CreateAgentVersionFromCodeMetadata(
description="Hello-world code agent",
definition=HostedAgentDefinition(
cpu="1",
memory="2Gi",
code_configuration=CodeConfiguration(
runtime="python_3_13",
entry_point=["python", "main.py"],
dependency_resolution="remote_build",
),
protocol_versions=[
ProtocolVersionRecord(protocol="responses", version="1.0.0")
],
environment_variables={"AZURE_AI_MODEL_DEPLOYMENT_NAME": "gpt-4.1-mini"},
),
),
code=(ZIP_PATH.name, code_zip_bytes, "application/zip"),
)
created = project.beta.agents.create_version_from_code(
agent_name=AGENT_NAME,
content=content,
code_zip_sha256=code_zip_sha256,
)
print(f"Created version: {created.version}")
For the Invocations protocol, set the protocol_versions entry to ProtocolVersionRecord(protocol="invocations", version="1.0.0"). For bundled mode, set dependency_resolution="bundled" and ship prebuilt dependencies in the zip—see Build Linux dependencies locally.
Poll for active
The code-deploy methods (create_version_from_code and download_code) live on the preview project.beta.agents surface, but read and delete operations such as get_version are on project.agents.
import time
while True:
version = project.agents.get_version(
agent_name=AGENT_NAME, agent_version=created.version
)
status = version["status"]
print(f"Status: {status}")
if status == "active":
break
if status == "failed":
raise RuntimeError(f"Provisioning failed: {version.get('error')}")
time.sleep(5)
See Poll for active for the full list of status values and how to read the error object on failure.
Invoke the agent
After the version reaches active, bind an OpenAI client to the agent endpoint and call it. This example uses the Responses protocol:
openai_client = project.get_openai_client(agent_name=AGENT_NAME)
response = openai_client.responses.create(input="Hello! What can you do?")
print(response.output_text)
For the Invocations protocol, call the invoke endpoint directly with a bearer token, as shown in Invoke the agent.
Download the deployed zip
Verify exactly what's deployed by downloading the zip and comparing its SHA-256 against the value you uploaded:
import hashlib
from pathlib import Path
out_path = Path(f"{AGENT_NAME}-{created.version}.zip")
sha = hashlib.sha256()
with open(out_path, "wb") as f:
for chunk in project.beta.agents.download_code(
agent_name=AGENT_NAME, agent_version=created.version
):
f.write(chunk)
sha.update(chunk)
print(f"Downloaded {out_path} (matches upload: {sha.hexdigest() == code_zip_sha256})")
For a complete runnable example, see the Python hosted-agent samples.
Package the zip manually
If you use azd, skip this section—azd builds the zip for you. Read it if you use the REST API, if you switch to bundled dependency resolution, or if you need full control over the upload contents.
The zip must be flat at the root—no top-level wrapper folder.
Select the tab for your agent's language.
Python layout (remote build mode)
The service installs dependencies in the cloud from requirements.txt.
agent-code.zip
├── main.py
└── requirements.txt
Python layout (bundled mode)
You ship prebuilt Linux dependencies in packages/.
agent-code.zip
├── main.py # entry point
├── requirements.txt
└── packages/ # extracted modules (not raw .whl files)
├── azure/identity/__init__.py
└── requests/__init__.py
Build Linux dependencies locally (bundled, Python)
Use the manylinux2014_x86_64 platform tag so pip downloads Linux wheels even from Windows or macOS.
Bash
pip install -r requirements.txt \
--target packages/ \
--platform manylinux2014_x86_64 \
--python-version 3.13 \
--implementation cp \
--only-binary=:all:
zip -r agent-code.zip main.py requirements.txt packages/
PowerShell / Windows cmd
pip install -r requirements.txt --target packages --platform manylinux2014_x86_64 --python-version 3.13 --implementation cp --only-binary=:all:
tar -a -c -f agent-code.zip main.py requirements.txt packages
--only-binary=:all: forces wheels (no source builds). The --python-version must match the runtime value in the agent definition.
Warning
Common packaging mistakes that cause session_creation_failed or ModuleNotFoundError:
- Wrapping the source in a folder (
my-agent/main.pyinstead ofmain.pyat the root). - Including raw
.whlfiles inpackages/instead of extracted modules. - Bundling Windows binaries (
.pyd,.dll) for a Linux runtime.
Limits
| Limit | Value |
|---|---|
| Maximum zip size (multipart upload) | 250 MB |
For the supported cpu and memory combinations, see Sandbox sizes.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
401 Unauthorized |
Missing or wrong-scope token | Acquire a token with --resource https://ai.azure.com. |
403 Forbidden |
Caller lacks Role Based Access Control on the project | Grant Foundry User (or higher) at project scope. |
409 conflict on Create (Agent '<name>' already exists) |
Agent name already exists | Use Update (POST /agents/{name}), or pick a new name. |
400 bad_request (CPU and Memory must be specified as a valid resource tier) on Create or Update |
cpu/memory aren't one of the supported tiers |
Set cpu and memory to a valid pair from Sandbox sizes. |
400 bad_request (Agent version is still being provisioned) on invoke |
A new version is mid-deploy and the active version is being swapped in | Poll the version status until active, then retry. |
424 session_not_ready on invoke |
Container started but /readiness didn't return HTTP 200 within the timeout |
Stream logs with :logstream, fix the readiness probe or startup error, redeploy. |
409 conflict on DELETE agent (Agent has active sessions) |
Open sessions block deletion | Wait for sessions to go idle, or append &force=true to cascade-delete sessions. |
Version stuck in creating (>10 min, remote build) |
Server build failed or couldn't resolve requirements.txt |
Switch to dependency_resolution: bundled and prebuild locally. |
Version transitions to failed |
Bad zip layout, syntax error, or (remote_build) a restore/compile failure |
Read the version's error object first—error.code classifies the failure and error.message contains the underlying restore or compile error line (pip for Python, NuGet for .NET) plus a troubleshooting link. Verify the folder structure. Use :logstream only after the container starts. |
ModuleNotFoundError at runtime |
packages/ missing, contains raw .whl files, or has Windows binaries |
Rebuild with pip install --target packages/ --platform manylinux2014_x86_64 --only-binary=:all:. |
409 AgentNotCodeBased on download |
Agent is image-based | Use the container-based deploy doc. |
Clean up resources
If you scaffolded the project from the Quickstart with azd, run azd down from the project root to remove the entire provisioned environment.
To delete an agent you deployed with the SDK or REST API, use the matching path below.
# Delete one version
project.agents.delete_version(agent_name=AGENT_NAME, agent_version=created.version)
# Delete the agent and all its versions
project.agents.delete(agent_name=AGENT_NAME)
Warning
Deleting an agent removes all of its versions and terminates active sessions. This action can't be undone.