From fbcebe1bdb770f09292deef191aa643d601acc86 Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Wed, 8 Jul 2026 20:33:47 -0400 Subject: [PATCH 1/2] Add `Async` prefix to generated AWS client names Async clients are renamed from `Client` to `AsyncClient` to match the Python convention. The old name remains as a deprecated alias (via module `__getattr__` + `TYPE_CHECKING` binding) that warns and returns the async client; it will be removed once sync clients land. Also bump codegen to 0.4.0. --- CHANGELOG.md | 26 +++++++--- .../aws/codegen/AwsServiceIdIntegration.java | 10 +++- .../codegen/AwsServiceIdIntegrationTest.java | 50 +++++++++++++++++++ codegen/build.gradle.kts | 2 +- .../python/codegen/ClientGenerator.java | 24 +++++++++ .../python/codegen/SymbolProperties.java | 6 +++ 6 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 codegen/aws/core/src/test/java/software/amazon/smithy/python/aws/codegen/AwsServiceIdIntegrationTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 14b923414..d6956cbcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,27 @@ ## Unreleased +## v0.4.0 + ### Breaking Changes -* Removed the `http_client` config option in favor of the generic `transport`. +* Renamed generated AWS service clients to include `Async` (e.g. + `BedrockRuntimeClient` is now `AsyncBedrockRuntimeClient`) to match the + Python community convention for async clients. The old name is still + available as a deprecated alias that emits a `DeprecationWarning`, and will + be removed in an upcoming release. The unprefixed name will later be + reintroduced for synchronous clients. -### Features + diff --git a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsServiceIdIntegration.java b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsServiceIdIntegration.java index 182d0184f..cb3b60e2a 100644 --- a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsServiceIdIntegration.java +++ b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsServiceIdIntegration.java @@ -11,6 +11,7 @@ import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.python.codegen.PythonSettings; +import software.amazon.smithy.python.codegen.SymbolProperties; import software.amazon.smithy.python.codegen.integrations.PythonIntegration; import software.amazon.smithy.utils.StringUtils; @@ -33,8 +34,13 @@ public Symbol toSymbol(Shape shape) { Symbol symbol = this.delegate.toSymbol(shape); if (shape.isServiceShape() && shape.hasTrait(ServiceTrait.class)) { var serviceTrait = shape.expectTrait(ServiceTrait.class); - var serviceName = StringUtils.capitalize(serviceTrait.getSdkId() + "Client").replace(" ", ""); - symbol = symbol.toBuilder().name(serviceName).build(); + var baseClientName = StringUtils.capitalize(serviceTrait.getSdkId() + "Client").replace(" ", ""); + var serviceName = "Async" + baseClientName; + var deprecatedName = baseClientName; + symbol = symbol.toBuilder() + .name(serviceName) + .putProperty(SymbolProperties.DEPRECATED_ALIAS, deprecatedName) + .build(); } return symbol; } diff --git a/codegen/aws/core/src/test/java/software/amazon/smithy/python/aws/codegen/AwsServiceIdIntegrationTest.java b/codegen/aws/core/src/test/java/software/amazon/smithy/python/aws/codegen/AwsServiceIdIntegrationTest.java new file mode 100644 index 000000000..25278f868 --- /dev/null +++ b/codegen/aws/core/src/test/java/software/amazon/smithy/python/aws/codegen/AwsServiceIdIntegrationTest.java @@ -0,0 +1,50 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package software.amazon.smithy.python.aws.codegen; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.python.codegen.PythonSettings; +import software.amazon.smithy.python.codegen.PythonSymbolProvider; +import software.amazon.smithy.python.codegen.SymbolProperties; + +public class AwsServiceIdIntegrationTest { + + private static final String NS = "smithy.example"; + + @Test + public void testServiceSymbolUsesAsyncClientNameWithDeprecatedAlias() { + Model model = Model.assembler() + .discoverModels(AwsServiceIdIntegrationTest.class.getClassLoader()) + .addUnparsedModel("test.smithy", """ + $version: "2" + namespace smithy.example + + use aws.api#service + + @service(sdkId: "Bedrock Runtime") + service TestService { + version: "2024-01-01" + } + """) + .assemble() + .unwrap(); + PythonSettings settings = PythonSettings.builder() + .service(ShapeId.from(NS + "#TestService")) + .moduleName("test_client") + .moduleVersion("0.0.1") + .build(); + var integration = new AwsServiceIdIntegration(); + var provider = integration.decorateSymbolProvider(model, settings, new PythonSymbolProvider(model, settings)); + + var symbol = provider.toSymbol(model.expectShape(ShapeId.from(NS + "#TestService"))); + + assertEquals("AsyncBedrockRuntimeClient", symbol.getName()); + assertEquals("BedrockRuntimeClient", symbol.expectProperty(SymbolProperties.DEPRECATED_ALIAS)); + } +} diff --git a/codegen/build.gradle.kts b/codegen/build.gradle.kts index df6e5391c..af380a8b7 100644 --- a/codegen/build.gradle.kts +++ b/codegen/build.gradle.kts @@ -15,5 +15,5 @@ allprojects { group = "software.amazon.smithy.python" - version = "0.3.1" + version = "0.4.0" } diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java index 6a3f65c4a..e9f5d7a35 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java @@ -105,6 +105,30 @@ def __init__(self, config: $1T | None = None, plugins: list[$2T] | None = None): } } }); + + serviceSymbol.getProperty(SymbolProperties.DEPRECATED_ALIAS).ifPresent(alias -> { + writer.addStdlibImport("typing", "TYPE_CHECKING"); + writer.addStdlibImport("typing", "Any"); + writer.addStdlibImport("warnings"); + writer.write(""" + + if TYPE_CHECKING: + # Deprecated alias for backwards compatibility, to be removed. + $1L = $2L + + + def __getattr__(name: str) -> Any: + if name == $1S: + warnings.warn( + "$1L is deprecated, use $2L instead. " + "This alias will be removed in a future version.", + DeprecationWarning, + stacklevel=2, + ) + return $2L + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + """, alias, serviceSymbol.getName()); + }); } private void writeDefaultPlugins(PythonWriter writer, Collection plugins) { diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/SymbolProperties.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/SymbolProperties.java index 992b8af21..d41f86db6 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/SymbolProperties.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/SymbolProperties.java @@ -77,5 +77,11 @@ public final class SymbolProperties { */ public static final Property IMPORTABLE = Property.named("nonImportable"); + /** + * Contains a deprecated name for the symbol that is generated as an alias + * for backwards compatibility. This is only used for services. + */ + public static final Property DEPRECATED_ALIAS = Property.named("deprecatedAlias"); + private SymbolProperties() {} } From a7da73f436bb30527da86503f40339e692915756 Mon Sep 17 00:00:00 2001 From: jonathan343 Date: Thu, 9 Jul 2026 13:19:11 -0400 Subject: [PATCH 2/2] Only add the deprecated client alias for existing AWS services --- CHANGELOG.md | 9 ++--- .../aws/codegen/AwsServiceIdIntegration.java | 33 +++++++++++++++---- .../codegen/AwsServiceIdIntegrationTest.java | 29 +++++++++++----- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6956cbcc..997de51e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,11 @@ * Renamed generated AWS service clients to include `Async` (e.g. `BedrockRuntimeClient` is now `AsyncBedrockRuntimeClient`) to match the - Python community convention for async clients. The old name is still - available as a deprecated alias that emits a `DeprecationWarning`, and will - be removed in an upcoming release. The unprefixed name will later be - reintroduced for synchronous clients. + Python community convention for async clients. For clients that were already + published under the unprefixed name, the old name remains available as a + deprecated alias that emits a `DeprecationWarning` and will be removed in an + upcoming release. The unprefixed name will later be reintroduced for + synchronous clients.