From 5efb467ed24663cc9420d9e1380bd9d7f133d3f8 Mon Sep 17 00:00:00 2001 From: Abhimanyu Siwach Date: Wed, 30 Sep 2026 14:36:15 -0700 Subject: [PATCH] fix(bma): set requires-python >=3.12 so uv run client.py does not use an older system Python Without requires-python, uv can pick the macOS system Python 3.9 for client.py, and the openai dependency does not install on it. The image still installs the latest Python before it copies pyproject.toml, so the minimum does not pin the image. --- .../__snapshots__/assets.snapshot.test.ts.snap | 3 ++- src/assets/python/http/bma/base/README.md | 2 +- src/assets/python/http/bma/base/pyproject.toml | 1 + src/cli/templates/__tests__/bma.test.ts | 12 ++++++++++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap b/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap index 7f08e15b7b..285e085d41 100644 --- a/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +++ b/src/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap @@ -3917,7 +3917,7 @@ environment where BMA runs commands. The ACR has no model code. | \`otel/collector.yaml\` | The configuration of the CloudWatch agent. The agent gets the spans and logs of \`codex exec-server\`, puts the session ID on them, and sends them to X-Ray and CloudWatch Logs with the ACR role. To turn off observability, add \`DISABLE_ADOT_OBSERVABILITY\` with the value \`true\` to \`envVars\`. | | \`plugins/acr-report\` | A Codex plugin with the \`acr-report\` skill. The skill saves the Python version, the user ID, and the working directory in \`acr-report.txt\`. | | \`bma-acr-policy.json\` | Lets the ACR role call \`bedrock-mantle:RegisterEnvironment\` and \`bedrock-mantle:ConnectEnvironment\` on every Mantle project. To limit the role to your projects, change \`Resource\` to \`arn:aws:bedrock-mantle:::project/\`. | -| \`pyproject.toml\` | The Python dependencies. \`aws-opentelemetry-distro\` sends a span for each call from BMA and a child span for each step of the call, for example the state load or the exec-server start. \`bedrock-agentcore\` is the AgentCore SDK. The \`dev\` group has the dependencies of \`client.py\`, and the image does not install it. Each image build installs the latest Python and the latest releases. To pin them, run \`uv lock\` and keep \`uv.lock\` next to this file. | +| \`pyproject.toml\` | The Python dependencies. \`aws-opentelemetry-distro\` sends a span for each call from BMA and a child span for each step of the call, for example the state load or the exec-server start. \`bedrock-agentcore\` is the AgentCore SDK. The \`dev\` group has the dependencies of \`client.py\`, and the image does not install it. Each image build installs the latest Python and the latest releases. To pin them, run \`uv lock\` and keep \`uv.lock\` next to this file. \`requires-python\` sets only a minimum, 3.12, so that \`uv run client.py\` does not use an older system Python. | | \`client.py\` | A sample OpenAI SDK client. It creates a session in BMA, and BMA sends the session's commands to this ACR. | Do not change \`lifecycle/server.py\`. It must match the lifecycle calls that BMA makes. @@ -4933,6 +4933,7 @@ name = "{{ name }}" version = "0.1.0" description = "AgentCore Runtime environment for Bedrock Managed Agents" readme = "README.md" +requires-python = ">=3.12" dependencies = [ "aws-opentelemetry-distro", "bedrock-agentcore", diff --git a/src/assets/python/http/bma/base/README.md b/src/assets/python/http/bma/base/README.md index df09959dbe..931fad06bb 100644 --- a/src/assets/python/http/bma/base/README.md +++ b/src/assets/python/http/bma/base/README.md @@ -12,7 +12,7 @@ environment where BMA runs commands. The ACR has no model code. | `otel/collector.yaml` | The configuration of the CloudWatch agent. The agent gets the spans and logs of `codex exec-server`, puts the session ID on them, and sends them to X-Ray and CloudWatch Logs with the ACR role. To turn off observability, add `DISABLE_ADOT_OBSERVABILITY` with the value `true` to `envVars`. | | `plugins/acr-report` | A Codex plugin with the `acr-report` skill. The skill saves the Python version, the user ID, and the working directory in `acr-report.txt`. | | `bma-acr-policy.json` | Lets the ACR role call `bedrock-mantle:RegisterEnvironment` and `bedrock-mantle:ConnectEnvironment` on every Mantle project. To limit the role to your projects, change `Resource` to `arn:aws:bedrock-mantle:::project/`. | -| `pyproject.toml` | The Python dependencies. `aws-opentelemetry-distro` sends a span for each call from BMA and a child span for each step of the call, for example the state load or the exec-server start. `bedrock-agentcore` is the AgentCore SDK. The `dev` group has the dependencies of `client.py`, and the image does not install it. Each image build installs the latest Python and the latest releases. To pin them, run `uv lock` and keep `uv.lock` next to this file. | +| `pyproject.toml` | The Python dependencies. `aws-opentelemetry-distro` sends a span for each call from BMA and a child span for each step of the call, for example the state load or the exec-server start. `bedrock-agentcore` is the AgentCore SDK. The `dev` group has the dependencies of `client.py`, and the image does not install it. Each image build installs the latest Python and the latest releases. To pin them, run `uv lock` and keep `uv.lock` next to this file. `requires-python` sets only a minimum, 3.12, so that `uv run client.py` does not use an older system Python. | | `client.py` | A sample OpenAI SDK client. It creates a session in BMA, and BMA sends the session's commands to this ACR. | Do not change `lifecycle/server.py`. It must match the lifecycle calls that BMA makes. diff --git a/src/assets/python/http/bma/base/pyproject.toml b/src/assets/python/http/bma/base/pyproject.toml index 9bbb0ffa23..10a862ddd7 100644 --- a/src/assets/python/http/bma/base/pyproject.toml +++ b/src/assets/python/http/bma/base/pyproject.toml @@ -3,6 +3,7 @@ name = "{{ name }}" version = "0.1.0" description = "AgentCore Runtime environment for Bedrock Managed Agents" readme = "README.md" +requires-python = ">=3.12" dependencies = [ "aws-opentelemetry-distro", "bedrock-agentcore", diff --git a/src/cli/templates/__tests__/bma.test.ts b/src/cli/templates/__tests__/bma.test.ts index 26933d4ca3..17827fc832 100644 --- a/src/cli/templates/__tests__/bma.test.ts +++ b/src/cli/templates/__tests__/bma.test.ts @@ -183,11 +183,19 @@ describe('BmaRenderer', () => { expect(main).toContain('if not OBSERVABILITY_ENABLED or not self.runtime_session_id:\n return False\n'); }); - it('installs the latest Python and writes no Python version', () => { + it('installs the latest Python in the image and sets only a minimum for client.py', () => { const agentDir = join(outputDir, 'app', 'BmaEnv'); const dockerfile = readFileSync(join(agentDir, 'Dockerfile'), 'utf-8'); expect(dockerfile).toContain('RUN uv python install --default\n'); - for (const file of ['Dockerfile', 'pyproject.toml', 'client.py']) { + // The image installs Python before it copies pyproject.toml, so the minimum does not pin the image. + expect(dockerfile.indexOf('RUN uv python install --default')).toBeLessThan( + dockerfile.indexOf('COPY pyproject.toml') + ); + // Without a minimum, `uv run client.py` can pick the macOS system Python 3.9, which openai does not support. + const pyproject = readFileSync(join(agentDir, 'pyproject.toml'), 'utf-8'); + expect(pyproject).toContain('requires-python = ">=3.12"\n'); + expect(pyproject.replace('requires-python = ">=3.12"\n', '')).not.toMatch(/requires-python|python[\s-]*3\.\d+/i); + for (const file of ['Dockerfile', 'client.py']) { const content = readFileSync(join(agentDir, file), 'utf-8'); expect(content).not.toMatch(/requires-python|python[\s-]*3\.\d+|install 3\.\d+/i); }