Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion codegen-output/aws-query/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ classifiers = [
dependencies = [
"smithy_aws_core[xml]~=0.12.0",
"smithy_core~=0.9.0",
"smithy_http[aiohttp]~=0.6.0"
"smithy_http[aiohttp]~=0.6.0",
"smithy_xml~=0.2.0"
]

[project.optional-dependencies]
Expand Down
7 changes: 6 additions & 1 deletion codegen-output/aws-query/src/awsquery/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from smithy_core.serializers import SerializeableShape
from smithy_http.aio.interfaces import HTTPClient
from smithy_http.plugins import user_agent_plugin
from smithy_xml.plugins import xml_deserialization_plugin

from .config import AsyncQueryProtocolConfig, Plugin
from .models import (
Expand Down Expand Up @@ -145,7 +146,11 @@ def __init__(
super().__init__()
self._config = config
self._plugins = plugins
self._client_plugins: list[Plugin] = [aws_user_agent_plugin, user_agent_plugin]
self._client_plugins: list[Plugin] = [
aws_user_agent_plugin,
xml_deserialization_plugin,
user_agent_plugin,
]

async def _ensure_setup(self) -> AsyncQueryProtocolConfig:
if not self._setup_done:
Expand Down
9 changes: 9 additions & 0 deletions codegen-output/aws-query/src/awsquery/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from smithy_core.interfaces.auth import AuthSchemeResolver
from smithy_core.shapes import ShapeID
from smithy_http.aio.aiohttp import AIOHTTPClient
from smithy_xml import XMLDeserializationMode

from .auth import HTTPAuthSchemeResolver
from .models import (
Expand Down Expand Up @@ -165,6 +166,7 @@ class _AsyncQueryProtocolConfigOverrides(AwsConfigOverrides, total=False):
)
auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None
auth_scheme_resolver: AuthSchemeResolver | None
xml_deserialization_mode: XMLDeserializationMode | None


@dataclass(kw_only=True, repr=False, init=False)
Expand Down Expand Up @@ -228,6 +230,12 @@ class AsyncQueryProtocolConfig(AsyncAwsConfig):
header.
"""

xml_deserialization_mode: XMLDeserializationMode | None = None
"""
Controls whether XML response payloads are deserialized eagerly or
incrementally.
"""

_FIELDS: ClassVar[dict[str, FieldSpec]] = {
"aws_credentials_identity_resolver": FieldSpec(default=None),
"region": FieldSpec(default=None),
Expand All @@ -236,6 +244,7 @@ class AsyncQueryProtocolConfig(AsyncAwsConfig):
"aws_session_token": FieldSpec(default=None),
"user_agent_extra": FieldSpec(default=None),
"sdk_ua_app_id": FieldSpec(default=None),
"xml_deserialization_mode": FieldSpec(default=None),
**AsyncAwsConfig._FIELDS,
"endpoint_uri": FieldSpec(
default=None, resolver=EndpointUriResolver("query_protocol")
Expand Down
3 changes: 2 additions & 1 deletion codegen-output/ec2-query/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ classifiers = [
dependencies = [
"smithy_aws_core[xml]~=0.12.0",
"smithy_core~=0.9.0",
"smithy_http[aiohttp]~=0.6.0"
"smithy_http[aiohttp]~=0.6.0",
"smithy_xml~=0.2.0"
]

[project.optional-dependencies]
Expand Down
7 changes: 6 additions & 1 deletion codegen-output/ec2-query/src/ec2query/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from smithy_core.serializers import SerializeableShape
from smithy_http.aio.interfaces import HTTPClient
from smithy_http.plugins import user_agent_plugin
from smithy_xml.plugins import xml_deserialization_plugin

from .config import AsyncEC2ProtocolConfig, Plugin
from .models import (
Expand Down Expand Up @@ -121,7 +122,11 @@ def __init__(
super().__init__()
self._config = config
self._plugins = plugins
self._client_plugins: list[Plugin] = [aws_user_agent_plugin, user_agent_plugin]
self._client_plugins: list[Plugin] = [
aws_user_agent_plugin,
xml_deserialization_plugin,
user_agent_plugin,
]

async def _ensure_setup(self) -> AsyncEC2ProtocolConfig:
if not self._setup_done:
Expand Down
9 changes: 9 additions & 0 deletions codegen-output/ec2-query/src/ec2query/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from smithy_core.interfaces.auth import AuthSchemeResolver
from smithy_core.shapes import ShapeID
from smithy_http.aio.aiohttp import AIOHTTPClient
from smithy_xml import XMLDeserializationMode

from .auth import HTTPAuthSchemeResolver
from .models import (
Expand Down Expand Up @@ -134,6 +135,7 @@ class _AsyncEC2ProtocolConfigOverrides(AwsConfigOverrides, total=False):
)
auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None
auth_scheme_resolver: AuthSchemeResolver | None
xml_deserialization_mode: XMLDeserializationMode | None


@dataclass(kw_only=True, repr=False, init=False)
Expand Down Expand Up @@ -197,6 +199,12 @@ class AsyncEC2ProtocolConfig(AsyncAwsConfig):
header.
"""

xml_deserialization_mode: XMLDeserializationMode | None = None
"""
Controls whether XML response payloads are deserialized eagerly or
incrementally.
"""

_FIELDS: ClassVar[dict[str, FieldSpec]] = {
"aws_credentials_identity_resolver": FieldSpec(default=None),
"region": FieldSpec(default=None),
Expand All @@ -205,6 +213,7 @@ class AsyncEC2ProtocolConfig(AsyncAwsConfig):
"aws_session_token": FieldSpec(default=None),
"user_agent_extra": FieldSpec(default=None),
"sdk_ua_app_id": FieldSpec(default=None),
"xml_deserialization_mode": FieldSpec(default=None),
**AsyncAwsConfig._FIELDS,
"endpoint_uri": FieldSpec(
default=None, resolver=EndpointUriResolver("ec2_protocol")
Expand Down
3 changes: 2 additions & 1 deletion codegen-output/rest-xml-with-namespace/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ classifiers = [
dependencies = [
"smithy_aws_core[xml]~=0.12.0",
"smithy_core~=0.9.0",
"smithy_http[aiohttp]~=0.6.0"
"smithy_http[aiohttp]~=0.6.0",
"smithy_xml~=0.2.0"
]

[project.optional-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from smithy_core.serializers import SerializeableShape
from smithy_http.aio.interfaces import HTTPClient
from smithy_http.plugins import user_agent_plugin
from smithy_xml.plugins import xml_deserialization_plugin

from .config import AsyncRestXmlProtocolNamespaceConfig, Plugin
from .models import (
Expand Down Expand Up @@ -55,7 +56,11 @@ def __init__(
super().__init__()
self._config = config
self._plugins = plugins
self._client_plugins: list[Plugin] = [aws_user_agent_plugin, user_agent_plugin]
self._client_plugins: list[Plugin] = [
aws_user_agent_plugin,
xml_deserialization_plugin,
user_agent_plugin,
]

async def _ensure_setup(self) -> AsyncRestXmlProtocolNamespaceConfig:
if not self._setup_done:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from smithy_core.interfaces.auth import AuthSchemeResolver
from smithy_core.shapes import ShapeID
from smithy_http.aio.aiohttp import AIOHTTPClient
from smithy_xml import XMLDeserializationMode

from .auth import HTTPAuthSchemeResolver
from .models import SimpleScalarPropertiesInput, SimpleScalarPropertiesOutput
Expand All @@ -47,6 +48,7 @@ class _AsyncRestXmlProtocolNamespaceConfigOverrides(AwsConfigOverrides, total=Fa
)
auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None
auth_scheme_resolver: AuthSchemeResolver | None
xml_deserialization_mode: XMLDeserializationMode | None


@dataclass(kw_only=True, repr=False, init=False)
Expand Down Expand Up @@ -110,6 +112,12 @@ class AsyncRestXmlProtocolNamespaceConfig(AsyncAwsConfig):
header.
"""

xml_deserialization_mode: XMLDeserializationMode | None = None
"""
Controls whether XML response payloads are deserialized eagerly or
incrementally.
"""

_FIELDS: ClassVar[dict[str, FieldSpec]] = {
"aws_credentials_identity_resolver": FieldSpec(default=None),
"region": FieldSpec(default=None),
Expand All @@ -118,6 +126,7 @@ class AsyncRestXmlProtocolNamespaceConfig(AsyncAwsConfig):
"aws_session_token": FieldSpec(default=None),
"user_agent_extra": FieldSpec(default=None),
"sdk_ua_app_id": FieldSpec(default=None),
"xml_deserialization_mode": FieldSpec(default=None),
**AsyncAwsConfig._FIELDS,
"endpoint_uri": FieldSpec(
default=None, resolver=EndpointUriResolver("rest_xml_protocol_namespace")
Expand Down
3 changes: 2 additions & 1 deletion codegen-output/rest-xml/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ classifiers = [
dependencies = [
"smithy_aws_core[xml]~=0.12.0",
"smithy_core~=0.9.0",
"smithy_http[aiohttp]~=0.6.0"
"smithy_http[aiohttp]~=0.6.0",
"smithy_xml~=0.2.0"
]

[project.optional-dependencies]
Expand Down
7 changes: 6 additions & 1 deletion codegen-output/rest-xml/src/restxml/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from smithy_core.serializers import SerializeableShape
from smithy_http.aio.interfaces import HTTPClient
from smithy_http.plugins import user_agent_plugin
from smithy_xml.plugins import xml_deserialization_plugin

from .config import AsyncRestXmlProtocolConfig, Plugin
from .models import (
Expand Down Expand Up @@ -241,7 +242,11 @@ def __init__(
super().__init__()
self._config = config
self._plugins = plugins
self._client_plugins: list[Plugin] = [aws_user_agent_plugin, user_agent_plugin]
self._client_plugins: list[Plugin] = [
aws_user_agent_plugin,
xml_deserialization_plugin,
user_agent_plugin,
]

async def _ensure_setup(self) -> AsyncRestXmlProtocolConfig:
if not self._setup_done:
Expand Down
9 changes: 9 additions & 0 deletions codegen-output/rest-xml/src/restxml/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from smithy_core.interfaces.auth import AuthSchemeResolver
from smithy_core.shapes import ShapeID
from smithy_http.aio.aiohttp import AIOHTTPClient
from smithy_xml import XMLDeserializationMode

from .auth import HTTPAuthSchemeResolver
from .models import (
Expand Down Expand Up @@ -312,6 +313,7 @@ class _AsyncRestXmlProtocolConfigOverrides(AwsConfigOverrides, total=False):
)
auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None
auth_scheme_resolver: AuthSchemeResolver | None
xml_deserialization_mode: XMLDeserializationMode | None


@dataclass(kw_only=True, repr=False, init=False)
Expand Down Expand Up @@ -375,6 +377,12 @@ class AsyncRestXmlProtocolConfig(AsyncAwsConfig):
header.
"""

xml_deserialization_mode: XMLDeserializationMode | None = None
"""
Controls whether XML response payloads are deserialized eagerly or
incrementally.
"""

_FIELDS: ClassVar[dict[str, FieldSpec]] = {
"aws_credentials_identity_resolver": FieldSpec(default=None),
"region": FieldSpec(default=None),
Expand All @@ -383,6 +391,7 @@ class AsyncRestXmlProtocolConfig(AsyncAwsConfig):
"aws_session_token": FieldSpec(default=None),
"user_agent_extra": FieldSpec(default=None),
"sdk_ua_app_id": FieldSpec(default=None),
"xml_deserialization_mode": FieldSpec(default=None),
**AsyncAwsConfig._FIELDS,
"endpoint_uri": FieldSpec(
default=None, resolver=EndpointUriResolver("rest_xml_protocol")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ public final class SmithyPythonDependency {
Type.DEPENDENCY,
false);

/**
* The core smithy-xml python package.
*/
public static final PythonDependency SMITHY_XML = new PythonDependency(
"smithy_xml",
"~=0.2.0",
Type.DEPENDENCY,
false);

/**
* The core smithy-cbor python package.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.python.codegen.integrations;

import java.util.List;
import java.util.Set;
import software.amazon.smithy.aws.traits.protocols.AwsQueryTrait;
import software.amazon.smithy.aws.traits.protocols.Ec2QueryTrait;
import software.amazon.smithy.aws.traits.protocols.RestXmlTrait;
import software.amazon.smithy.codegen.core.Symbol;
import software.amazon.smithy.codegen.core.SymbolReference;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.python.codegen.ConfigProperty;
import software.amazon.smithy.python.codegen.GenerationContext;
import software.amazon.smithy.python.codegen.SmithyPythonDependency;
import software.amazon.smithy.utils.SmithyInternalApi;

/**
* Adds configurable XML deserialization to clients that support an XML protocol.
*/
@SmithyInternalApi
public final class XmlDeserializationIntegration implements PythonIntegration {
private static final Set<ShapeId> XML_PROTOCOLS = Set.of(
RestXmlTrait.ID,
AwsQueryTrait.ID,
Ec2QueryTrait.ID);

@Override
public List<RuntimeClientPlugin> getClientPlugins(GenerationContext context) {
var protocolGenerator = context.protocolGenerator();
if (protocolGenerator == null || !isXmlProtocol(protocolGenerator.getProtocol())) {
return List.of();
}

var mode = Symbol.builder()
.name("XMLDeserializationMode")
.namespace("smithy_xml", ".")
.addDependency(SmithyPythonDependency.SMITHY_XML)
.build();
var plugin = SymbolReference.builder()
.symbol(Symbol.builder()
.name("xml_deserialization_plugin")
.namespace("smithy_xml.plugins", ".")
.addDependency(SmithyPythonDependency.SMITHY_XML)
.build())
.build();
var property = ConfigProperty.builder()
.name("xml_deserialization_mode")
.type(mode)
.documentation(
"Controls whether XML response payloads are deserialized eagerly or incrementally.")
.nullable(true)
.build();

return List.of(RuntimeClientPlugin.builder()
.addConfigProperty(property)
.pythonPlugin(plugin)
.build());
}

static boolean isXmlProtocol(ShapeId protocol) {
return XML_PROTOCOLS.contains(protocol);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#

software.amazon.smithy.python.codegen.integrations.RestJsonIntegration
software.amazon.smithy.python.codegen.integrations.XmlDeserializationIntegration
software.amazon.smithy.python.codegen.integrations.Rpcv2CborIntegration
software.amazon.smithy.python.codegen.integrations.HttpApiKeyAuth
software.amazon.smithy.python.codegen.integrations.UserAgentIntegration
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.amazon.smithy.python.codegen.integrations;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;
import software.amazon.smithy.aws.traits.protocols.AwsQueryTrait;
import software.amazon.smithy.aws.traits.protocols.Ec2QueryTrait;
import software.amazon.smithy.aws.traits.protocols.RestXmlTrait;
import software.amazon.smithy.model.shapes.ShapeId;

public class XmlDeserializationIntegrationTest {
@Test
public void detectsXmlProtocols() {
assertTrue(XmlDeserializationIntegration.isXmlProtocol(RestXmlTrait.ID));
assertTrue(XmlDeserializationIntegration.isXmlProtocol(AwsQueryTrait.ID));
assertTrue(XmlDeserializationIntegration.isXmlProtocol(Ec2QueryTrait.ID));
assertFalse(XmlDeserializationIntegration.isXmlProtocol(ShapeId.from("example#other")));
}
}
Loading
Loading