Skip to content

Commit 53a4c13

Browse files
PDM-892 mypy fixes and setup-java action update
1 parent e8c0b72 commit 53a4c13

File tree

6 files changed

+63
-19
lines changed

6 files changed

+63
-19
lines changed

.gitallowed

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11

22
token: \$\{\{ secrets.GITHUB_TOKEN \}\}
3-
"token": response.get\("SessionToken"\)
3+
"token": response\["SessionToken"\]
44
token=credentials\["token"\]
5+
arn:aws:iam::000000000000:root
6+
account_id=\"000000000000\"
57

68
.*(GITHUB|SONAR)_TOKEN: \$\{\{ secrets.(GITHUB|SONAR)_TOKEN \}\}
79
.*asttokens = ">=2.1.0"

.github/workflows/merge-develop.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858

5959
- name: setup java
6060
if: github.actor != 'dependabot[bot]' && (success() || failure())
61-
uses: actions/setup-java@v4
61+
uses: actions/setup-java@v5
6262
with:
6363
distribution: "corretto"
6464
java-version: "17"

.github/workflows/pull-request.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
tox:
1212
strategy:
1313
matrix:
14-
python-version: ["3.9", "3.10", "3.11"]
14+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
1515

1616
runs-on: ubuntu-latest
1717
if: github.repository == 'NHSDigital/nhs-aws-helpers'
@@ -145,7 +145,7 @@ jobs:
145145

146146
- name: setup java
147147
if: success() || failure()
148-
uses: actions/setup-java@v4
148+
uses: actions/setup-java@v5
149149
with:
150150
distribution: "corretto"
151151
java-version: "17"

nhs_aws_helpers/__init__.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
from mypy_boto3_ssm.client import SSMClient
7676
from mypy_boto3_stepfunctions import SFNClient
7777
from mypy_boto3_sts.client import STSClient
78+
from mypy_boto3_sts.type_defs import AssumeRoleRequestTypeDef
7879

7980
from nhs_aws_helpers.common import run_in_executor
8081
from nhs_aws_helpers.s3_object_writer import S3ObjectWriter
@@ -1056,19 +1057,19 @@ def assumed_credentials(
10561057

10571058
sts_client = boto3.client("sts", region_name=region, endpoint_url=endpoint_url)
10581059

1059-
params = {
1060-
"RoleArn": f"arn:aws:iam::{account_id}:role/{role}",
1061-
"RoleSessionName": role_session_name,
1062-
"DurationSeconds": duration_seconds,
1063-
}
1060+
params = AssumeRoleRequestTypeDef(
1061+
RoleArn=f"arn:aws:iam::{account_id}:role/{role}",
1062+
RoleSessionName=role_session_name,
1063+
DurationSeconds=duration_seconds,
1064+
)
10641065

1065-
response = sts_client.assume_role(**params).get("Credentials")
1066+
response = sts_client.assume_role(**params)["Credentials"]
10661067

10671068
credentials = {
1068-
"access_key": response.get("AccessKeyId"),
1069-
"secret_key": response.get("SecretAccessKey"),
1070-
"token": response.get("SessionToken"),
1071-
"expiry_time": response.get("Expiration").isoformat(),
1069+
"access_key": response["AccessKeyId"],
1070+
"secret_key": response["SecretAccessKey"],
1071+
"token": response["SessionToken"],
1072+
"expiry_time": response["Expiration"].isoformat(),
10721073
}
10731074
return credentials
10741075

tests/aws_tests.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
import os
3-
from typing import Any, cast
3+
from typing import Any, Literal, TypedDict, cast
44
from uuid import uuid4
55

66
import pytest
@@ -10,6 +10,7 @@
1010
from pytest_httpserver import HTTPServer
1111

1212
from nhs_aws_helpers import (
13+
assumed_credentials,
1314
dynamodb_retry_backoff,
1415
post_create_client,
1516
register_config_default,
@@ -247,14 +248,20 @@ def test_s3_retries(
247248
key = f"{expected_folder}/filename.txt"
248249
httpserver.expect_request(f"/{temp_s3_bucket.name}/{key}").respond_with_json({}, status=503)
249250

251+
# Type-identical spec to match botocore's internal typing of _RetryDict
252+
class BotocoreRetries(TypedDict, total=False):
253+
total_max_attempts: int
254+
max_attempts: int
255+
mode: Literal["legacy", "standard", "adaptive"]
256+
250257
config = Config(
251258
connect_timeout=float(os.environ.get("BOTO_CONNECT_TIMEOUT", "1")),
252259
read_timeout=float(os.environ.get("BOTO_READ_TIMEOUT", "1")),
253260
max_pool_connections=int(os.environ.get("BOTO_MAX_POOL_CONNECTIONS", "10")),
254-
retries={
255-
"mode": os.environ.get("BOTO_RETRIES_MODE", "standard"), # type: ignore[typeddict-item]
256-
"total_max_attempts": int(os.environ.get("BOTO_RETRIES_TOTAL_MAX_ATTEMPTS", "2")),
257-
},
261+
retries=BotocoreRetries(
262+
mode=os.environ.get("BOTO_RETRIES_MODE", "standard"), # type: ignore[typeddict-item]
263+
total_max_attempts=int(os.environ.get("BOTO_RETRIES_TOTAL_MAX_ATTEMPTS", "2")),
264+
),
258265
)
259266

260267
def _post_create_aws(boto_module: str, _: str, client):
@@ -359,3 +366,13 @@ def test_s3_upload_multipart_from_copy_missing_part_data(temp_s3_bucket: Bucket)
359366
target_object.get()
360367

361368
assert client_error.value.response["Error"]["Code"] == "NoSuchKey"
369+
370+
371+
def test_assumed_credentials():
372+
creds = assumed_credentials(
373+
account_id="000000000000", role="MyRole", sts_endpoint_url=os.environ["AWS_ENDPOINT_URL"]
374+
)
375+
assert creds["access_key"]
376+
assert creds["secret_key"]
377+
assert creds["token"]
378+
assert creds["expiry_time"]

tests/client_tests.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from nhs_aws_helpers import ecs_client, healthlake_client, sts_client
2+
3+
4+
def test_sts_client():
5+
client = sts_client()
6+
assert client.meta.service_model.service_id == "STS"
7+
8+
identity = client.get_caller_identity()
9+
assert identity["Account"] == "000000000000"
10+
assert identity["Arn"] == "arn:aws:iam::000000000000:root"
11+
12+
13+
def test_healthlake_client():
14+
client = healthlake_client()
15+
# localstack pro subscription required for HealthLake support
16+
# so just check the client is created correctly
17+
assert client.meta.service_model.service_id == "HealthLake"
18+
19+
20+
def test_ecs_client():
21+
client = ecs_client()
22+
# localstack pro subscription required for ECS support
23+
# so just check the client is created correctly
24+
assert client.meta.service_model.service_id == "ECS"

0 commit comments

Comments
 (0)