From 054a936e4d193b22ea86af5512d470145a063fb7 Mon Sep 17 00:00:00 2001 From: George Fu Date: Mon, 21 Sep 2026 16:10:04 +0000 Subject: [PATCH] Add codegen-output folder for visual diff inspection chore: deterministic recursive-member ordering + formatted golden snapshot --- .github/workflows/ci.yml | 2 +- .licenserc.yaml | 1 + Makefile | 22 + codegen-output/aws-json-1-0/README.md | 5 + codegen-output/aws-json-1-0/pyproject.toml | 66 + .../aws-json-1-0/src/awsjson10/__init__.py | 3 + .../src/awsjson10/_private/__init__.py | 1 + .../src/awsjson10/_private/schemas.py | 2844 +++ .../aws-json-1-0/src/awsjson10/auth.py | 31 + .../aws-json-1-0/src/awsjson10/client.py | 1254 + .../aws-json-1-0/src/awsjson10/config.py | 229 + .../aws-json-1-0/src/awsjson10/models.py | 3351 +++ .../aws-json-1-0/src/awsjson10/user_agent.py | 17 + codegen-output/aws-json-1-0/tests/__init__.py | 1 + .../tests/test_awsjson10_protocol.py | 3734 +++ codegen-output/aws-json-1-1/README.md | 5 + codegen-output/aws-json-1-1/pyproject.toml | 66 + .../aws-json-1-1/src/awsjson11/__init__.py | 3 + .../src/awsjson11/_private/__init__.py | 1 + .../src/awsjson11/_private/schemas.py | 3551 +++ .../aws-json-1-1/src/awsjson11/auth.py | 31 + .../aws-json-1-1/src/awsjson11/client.py | 1381 ++ .../aws-json-1-1/src/awsjson11/config.py | 229 + .../aws-json-1-1/src/awsjson11/models.py | 4187 ++++ .../aws-json-1-1/src/awsjson11/user_agent.py | 17 + codegen-output/aws-json-1-1/tests/__init__.py | 1 + .../tests/test_awsjson11_protocol.py | 6515 ++++++ codegen-output/aws-query/README.md | 9 + codegen-output/aws-query/pyproject.toml | 66 + .../aws-query/src/awsquery/__init__.py | 3 + .../src/awsquery/_private/__init__.py | 1 + .../src/awsquery/_private/schemas.py | 3032 +++ codegen-output/aws-query/src/awsquery/auth.py | 31 + .../aws-query/src/awsquery/client.py | 2448 ++ .../aws-query/src/awsquery/config.py | 285 + .../aws-query/src/awsquery/models.py | 4982 ++++ .../aws-query/src/awsquery/user_agent.py | 17 + codegen-output/aws-query/tests/__init__.py | 1 + .../aws-query/tests/test_awsquery_protocol.py | 4430 ++++ codegen-output/rest-json-1/README.md | 5 + codegen-output/rest-json-1/pyproject.toml | 66 + .../rest-json-1/src/restjson/__init__.py | 3 + .../src/restjson/_private/__init__.py | 1 + .../src/restjson/_private/schemas.py | 19306 ++++++++++++++++ .../rest-json-1/src/restjson/auth.py | 31 + .../rest-json-1/src/restjson/client.py | 8184 +++++++ .../rest-json-1/src/restjson/config.py | 674 + .../rest-json-1/src/restjson/models.py | 17038 ++++++++++++++ .../rest-json-1/src/restjson/user_agent.py | 17 + codegen-output/rest-json-1/tests/__init__.py | 1 + .../tests/test_restjson_protocol.py | 14303 ++++++++++++ .../codegen/generators/SchemaGenerator.java | 6 +- 52 files changed, 102485 insertions(+), 3 deletions(-) create mode 100644 codegen-output/aws-json-1-0/README.md create mode 100644 codegen-output/aws-json-1-0/pyproject.toml create mode 100644 codegen-output/aws-json-1-0/src/awsjson10/__init__.py create mode 100644 codegen-output/aws-json-1-0/src/awsjson10/_private/__init__.py create mode 100644 codegen-output/aws-json-1-0/src/awsjson10/_private/schemas.py create mode 100644 codegen-output/aws-json-1-0/src/awsjson10/auth.py create mode 100644 codegen-output/aws-json-1-0/src/awsjson10/client.py create mode 100644 codegen-output/aws-json-1-0/src/awsjson10/config.py create mode 100644 codegen-output/aws-json-1-0/src/awsjson10/models.py create mode 100644 codegen-output/aws-json-1-0/src/awsjson10/user_agent.py create mode 100644 codegen-output/aws-json-1-0/tests/__init__.py create mode 100644 codegen-output/aws-json-1-0/tests/test_awsjson10_protocol.py create mode 100644 codegen-output/aws-json-1-1/README.md create mode 100644 codegen-output/aws-json-1-1/pyproject.toml create mode 100644 codegen-output/aws-json-1-1/src/awsjson11/__init__.py create mode 100644 codegen-output/aws-json-1-1/src/awsjson11/_private/__init__.py create mode 100644 codegen-output/aws-json-1-1/src/awsjson11/_private/schemas.py create mode 100644 codegen-output/aws-json-1-1/src/awsjson11/auth.py create mode 100644 codegen-output/aws-json-1-1/src/awsjson11/client.py create mode 100644 codegen-output/aws-json-1-1/src/awsjson11/config.py create mode 100644 codegen-output/aws-json-1-1/src/awsjson11/models.py create mode 100644 codegen-output/aws-json-1-1/src/awsjson11/user_agent.py create mode 100644 codegen-output/aws-json-1-1/tests/__init__.py create mode 100644 codegen-output/aws-json-1-1/tests/test_awsjson11_protocol.py create mode 100644 codegen-output/aws-query/README.md create mode 100644 codegen-output/aws-query/pyproject.toml create mode 100644 codegen-output/aws-query/src/awsquery/__init__.py create mode 100644 codegen-output/aws-query/src/awsquery/_private/__init__.py create mode 100644 codegen-output/aws-query/src/awsquery/_private/schemas.py create mode 100644 codegen-output/aws-query/src/awsquery/auth.py create mode 100644 codegen-output/aws-query/src/awsquery/client.py create mode 100644 codegen-output/aws-query/src/awsquery/config.py create mode 100644 codegen-output/aws-query/src/awsquery/models.py create mode 100644 codegen-output/aws-query/src/awsquery/user_agent.py create mode 100644 codegen-output/aws-query/tests/__init__.py create mode 100644 codegen-output/aws-query/tests/test_awsquery_protocol.py create mode 100644 codegen-output/rest-json-1/README.md create mode 100644 codegen-output/rest-json-1/pyproject.toml create mode 100644 codegen-output/rest-json-1/src/restjson/__init__.py create mode 100644 codegen-output/rest-json-1/src/restjson/_private/__init__.py create mode 100644 codegen-output/rest-json-1/src/restjson/_private/schemas.py create mode 100644 codegen-output/rest-json-1/src/restjson/auth.py create mode 100644 codegen-output/rest-json-1/src/restjson/client.py create mode 100644 codegen-output/rest-json-1/src/restjson/config.py create mode 100644 codegen-output/rest-json-1/src/restjson/models.py create mode 100644 codegen-output/rest-json-1/src/restjson/user_agent.py create mode 100644 codegen-output/rest-json-1/tests/__init__.py create mode 100644 codegen-output/rest-json-1/tests/test_restjson_protocol.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a4dc5ecd..e0815679b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,4 +69,4 @@ jobs: - name: Run protocol tests run: | - make test-protocols + make generate-protocol-tests test-protocols diff --git a/.licenserc.yaml b/.licenserc.yaml index a6fb34d75..e000755b0 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -14,6 +14,7 @@ header: - '**/*.java' - 'LICENSE' - 'NOTICE' + - 'codegen-output/**' - '**/smithy_core/rfc3986.py' language: diff --git a/Makefile b/Makefile index ec2452598..56d395123 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,28 @@ test-protocols: ## Generates and runs protocol tests for all supported protocols done +generate-protocol-tests: ## Generates protocol-test clients, copies them to ./codegen-output, and asserts no git diff. + cd codegen && ./gradlew :protocol-test:clean :protocol-test:build + rm -rf codegen-output + mkdir -p codegen-output + @set -e; for projection_dir in codegen/protocol-test/build/smithyprojections/protocol-test/*/python-client-codegen; do \ + projection=$$(basename $$(dirname "$$projection_dir")); \ + echo "Copying $$projection -> codegen-output/$$projection"; \ + cp -r "$$projection_dir" "codegen-output/$$projection"; \ + echo "Formatting codegen-output/$$projection"; \ + uv run ruff check --fix "codegen-output/$$projection"; \ + uv run ruff format "codegen-output/$$projection"; \ + done + @if ! git diff --quiet --exit-code -- codegen-output || [ -n "$$(git ls-files --others --exclude-standard -- codegen-output)" ]; then \ + echo "ERROR: generated codegen-output differs from the committed snapshot."; \ + echo "Review the diff and commit it if the change is intended:"; \ + git --no-pager status --short -- codegen-output; \ + git --no-pager diff -- codegen-output; \ + exit 1; \ + fi + @echo "codegen-output is up to date." + + lint-py: ## Runs linters and formatters on the python packages. uv run ruff check packages --fix --config pyproject.toml uv run ruff format packages --config pyproject.toml diff --git a/codegen-output/aws-json-1-0/README.md b/codegen-output/aws-json-1-0/README.md new file mode 100644 index 000000000..a4363cb0e --- /dev/null +++ b/codegen-output/aws-json-1-0/README.md @@ -0,0 +1,5 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +## Sample Json 1.0 Protocol Service Client + +awsjson10 client diff --git a/codegen-output/aws-json-1-0/pyproject.toml b/codegen-output/aws-json-1-0/pyproject.toml new file mode 100644 index 000000000..6cacfbddd --- /dev/null +++ b/codegen-output/aws-json-1-0/pyproject.toml @@ -0,0 +1,66 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +[project] +name = "awsjson10" +version = "0.0.1" +description = "awsjson10 client" +readme = "README.md" +requires-python = ">=3.12" +keywords = ["smithy", "awsjson10"] +license = {text = "Apache-2.0"} +classifiers = [ + "Development Status :: 2 - Pre-Alpha", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Natural Language :: English", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14" +] + +dependencies = [ + "smithy_aws_core[json]~=0.11.0", + "smithy_core~=0.8.0", + "smithy_http[aiohttp]~=0.5.0" +] + +[project.optional-dependencies] +awscrt = [ + "smithy_http[awscrt]~=0.5.0" +] + +[dependency-groups] +test = [ + "pytest>=9.0.1,<10.0.0", + "pytest-asyncio>=1.3.0,<1.4.0" +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.pyright] +typeCheckingMode = "strict" +reportPrivateUsage = false +reportUnusedFunction = false +reportUnusedVariable = false +reportUnnecessaryComparison = false +reportUnusedClass = false +enableExperimentalFeatures = true + +[tool.ruff] +target-version = "py312" + +[tool.ruff.lint] +ignore = ["F841"] + +[tool.ruff.format] +skip-magic-trailing-comma = true + +[tool.pytest.ini_options] +python_classes = ["!Test"] +asyncio_mode = "auto" diff --git a/codegen-output/aws-json-1-0/src/awsjson10/__init__.py b/codegen-output/aws-json-1-0/src/awsjson10/__init__.py new file mode 100644 index 000000000..30f6d44e9 --- /dev/null +++ b/codegen-output/aws-json-1-0/src/awsjson10/__init__.py @@ -0,0 +1,3 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +__version__: str = "0.0.1" diff --git a/codegen-output/aws-json-1-0/src/awsjson10/_private/__init__.py b/codegen-output/aws-json-1-0/src/awsjson10/_private/__init__.py new file mode 100644 index 000000000..247be3e3d --- /dev/null +++ b/codegen-output/aws-json-1-0/src/awsjson10/_private/__init__.py @@ -0,0 +1 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. diff --git a/codegen-output/aws-json-1-0/src/awsjson10/_private/schemas.py b/codegen-output/aws-json-1-0/src/awsjson10/_private/schemas.py new file mode 100644 index 000000000..ace13e621 --- /dev/null +++ b/codegen-output/aws-json-1-0/src/awsjson10/_private/schemas.py @@ -0,0 +1,2844 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from types import MappingProxyType + +from smithy_core.prelude import ( + BLOB, + BOOLEAN, + BYTE, + DOCUMENT, + DOUBLE, + FLOAT, + INTEGER, + LONG, + SHORT, + STRING, + TIMESTAMP, + UNIT, +) +from smithy_core.schemas import Schema +from smithy_core.shapes import ShapeID, ShapeType +from smithy_core.traits import Trait + + +CLIENT_OPTIONAL_DEFAULTS = Schema.collection( + id=ShapeID("aws.protocoltests.json10#ClientOptionalDefaults"), + members={ + "member": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=0), + Trait.new(id=ShapeID("smithy.api#clientOptional")), + ], + } + }, +) + +COMPLEX_NESTED_ERROR_DATA = Schema.collection( + id=ShapeID("aws.protocoltests.json10#ComplexNestedErrorData"), + members={ + "Foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#jsonName"), value="Fooooo")], + } + }, +) + +COMPLEX_ERROR = Schema.collection( + id=ShapeID("aws.protocoltests.json10#ComplexError"), + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10ComplexError", + "documentation": "Parses a complex error with no message member", + "protocol": "aws.protocols#awsJson1_0", + "params": MappingProxyType( + { + "TopLevel": "Top level", + "Nested": MappingProxyType({"Foo": "bar"}), + } + ), + "code": 400, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "__type": "aws.protocoltests.json10#ComplexError",\n "TopLevel": "Top level",\n "Nested": {\n "Foo": "bar"\n }\n}', + "bodyMediaType": "application/json", + } + ), + MappingProxyType( + { + "id": "AwsJson10EmptyComplexError", + "documentation": "Parses a complex error with an empty body", + "protocol": "aws.protocols#awsJson1_0", + "code": 400, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "__type": "aws.protocoltests.json10#ComplexError"\n}', + "bodyMediaType": "application/json", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="client"), + ], + members={ + "TopLevel": {"target": STRING}, + "Nested": {"target": COMPLEX_NESTED_ERROR_DATA}, + }, +) + +CONTENT_TYPE_PARAMETERS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#ContentTypeParametersInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"value": {"target": INTEGER}}, +) + +CONTENT_TYPE_PARAMETERS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#ContentTypeParametersOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], +) + +CONTENT_TYPE_PARAMETERS = Schema( + id=ShapeID("aws.protocoltests.json10#ContentTypeParameters"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10MustSupportParametersInContentType", + "documentation": "A server should ignore parameters added to the content type", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0; charset=utf-8", + "X-Amz-Target": "JsonRpc10.ContentTypeParameters", + } + ), + "uri": "/", + "body": '{"value":5}', + "bodyMediaType": "application/json", + "params": MappingProxyType({"value": 5}), + "appliesTo": "server", + } + ), + ), + ) + ], +) + +TEST_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.json10#TestEnum"), + shape_type=ShapeType.ENUM, + members={ + "FOO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="FOO")], + }, + "BAR": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="BAR")], + }, + "BAZ": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="BAZ")], + }, + }, +) + +TEST_INT_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.json10#TestIntEnum"), + shape_type=ShapeType.INT_ENUM, + traits=[Trait.new(id=ShapeID("smithy.api#box"))], + members={ + "ONE": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=1)], + }, + "TWO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=2)], + }, + }, +) + +TEST_STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.json10#TestStringList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING}}, +) + +TEST_STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.json10#TestStringMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +DEFAULTS = Schema.collection( + id=ShapeID("aws.protocoltests.json10#Defaults"), + members={ + "defaultString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "defaultBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=True)], + }, + "defaultList": { + "target": TEST_STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "defaultDocumentMap": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + "defaultDocumentString": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "defaultDocumentBoolean": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=True)], + }, + "defaultDocumentList": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "defaultNullDocument": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=None)], + }, + "defaultTimestamp": { + "target": TIMESTAMP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "defaultBlob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="YWJj")], + }, + "defaultByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "defaultShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "defaultInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=10)], + }, + "defaultLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=100)], + }, + "defaultFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1.0)], + }, + "defaultDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1.0)], + }, + "defaultMap": { + "target": TEST_STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + "defaultEnum": { + "target": TEST_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="FOO")], + }, + "defaultIntEnum": { + "target": TEST_INT_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "emptyString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="")], + }, + "falseBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=False)], + }, + "emptyBlob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="")], + }, + "zeroByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0.0)], + }, + "zeroDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0.0)], + }, + }, +) + +FAREWELL = Schema.collection( + id=ShapeID("aws.protocoltests.json10#Farewell"), + members={ + "phrase": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="bye")], + } + }, +) + +DIALOG = Schema.collection( + id=ShapeID("aws.protocoltests.json10#Dialog"), + members={ + "language": {"target": STRING}, + "greeting": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "farewell": {"target": FAREWELL}, + }, +) + +DIALOG_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.json10#DialogList"), + shape_type=ShapeType.LIST, + members={"member": {"target": DIALOG}}, +) + +DIALOG_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.json10#DialogMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": DIALOG}}, +) + +EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#EmptyInputAndEmptyOutputInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], +) + +EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#EmptyInputAndEmptyOutputOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], +) + +EMPTY_INPUT_AND_EMPTY_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.json10#EmptyInputAndEmptyOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10EmptyInputAndEmptyOutput", + "documentation": "Clients must always send an empty object if input is modeled.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.EmptyInputAndEmptyOutput", + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10EmptyInputAndEmptyOutputSendJsonObject", + "documentation": "A service will always return a JSON object for operations with modeled output.", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + } + ), + ), + ), + ], +) + +ENDPOINT_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#EndpointOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +ENDPOINT_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#EndpointOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +ENDPOINT_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json10#EndpointOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10EndpointTrait", + "documentation": "Operations can prepend to the given host if they define the\nendpoint trait.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": "{}", + "host": "example.com", + "resolvedHost": "foo.example.com", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#endpoint"), + value=MappingProxyType({"hostPrefix": "foo."}), + ), + ], +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#EndpointWithHostLabelOperationInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "label": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#hostLabel")), + Trait.new(id=ShapeID("smithy.api#required")), + ], + } + }, +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#EndpointWithHostLabelOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json10#EndpointWithHostLabelOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10EndpointTraitWithHostLabel", + "documentation": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{"label": "bar"}', + "bodyMediaType": "application/json", + "host": "example.com", + "resolvedHost": "foo.bar.example.com", + "params": MappingProxyType({"label": "bar"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#endpoint"), + value=MappingProxyType({"hostPrefix": "foo.{label}."}), + ), + ], +) + +FOO_ERROR = Schema.collection( + id=ShapeID("aws.protocoltests.json10#FooError"), + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10FooErrorUsingXAmznErrorType", + "documentation": "Serializes the X-Amzn-ErrorType header. For an example service, see Amazon EKS.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType({"X-Amzn-Errortype": "FooError"}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorUsingXAmznErrorTypeWithUri", + "documentation": "Some X-Amzn-Errortype headers contain URLs. Clients need to split the URL on ':' and take only the first half of the string. For example, 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/'\nis to be interpreted as 'ValidationException'.\n\nFor an example service see Amazon Polly.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + { + "X-Amzn-Errortype": "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "documentation": "X-Amzn-Errortype might contain a URL and a namespace. Client should extract only the shape name. This is a pathalogical case that might not actually happen in any deployed AWS service.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + { + "X-Amzn-Errortype": "aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorUsingCode", + "documentation": "This example uses the 'code' property in the output rather than X-Amzn-Errortype. Some services do this though it's preferable to send the X-Amzn-Errortype. Client implementations must first check for the X-Amzn-Errortype and then check for a top-level 'code' property.\n\nFor example service see Amazon S3 Glacier.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "code": "FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorUsingCodeAndNamespace", + "documentation": "Some services serialize errors using code, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "code": "aws.protocoltests.json10#FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorUsingCodeUriAndNamespace", + "documentation": "Some services serialize errors using code, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "code": "aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorWithDunderType", + "documentation": "Some services serialize errors using __type.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "__type": "FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorWithDunderTypeAndNamespace", + "documentation": "Some services serialize errors using __type, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "__type": "aws.protocoltests.json10#FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorWithDunderTypeAndDifferentNamespace", + "documentation": "Because only the part after '#' is considered, an unrecognized namespace should not make a difference.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "__type": "aws.different.namespace#FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorWithDunderTypeUriAndNamespace", + "documentation": "Some services serialize errors using __type, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "__type": "aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10FooErrorWithNestedTypeProperty", + "documentation": "Some services serialize errors using __type, and if the response includes additional shapes that belong to a different namespace there'll be a nested __type property that must not be considered when determining which error to be surfaced.\n\nFor an example service see Amazon DynamoDB.", + "protocol": "aws.protocols#awsJson1_0", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "__type": "aws.protocoltests.json10#FooError",\n "ErrorDetails": [\n {\n "__type": "com.amazon.internal#ErrorDetails",\n "reason": "Some reason"\n }\n ]\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="server"), + ], +) + +GREETING_WITH_ERRORS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#GreetingWithErrorsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"greeting": {"target": STRING}}, +) + +GREETING_WITH_ERRORS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#GreetingWithErrorsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"greeting": {"target": STRING}}, +) + +INVALID_GREETING = Schema.collection( + id=ShapeID("aws.protocoltests.json10#InvalidGreeting"), + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10InvalidGreetingError", + "documentation": "Parses simple JSON errors", + "protocol": "aws.protocols#awsJson1_0", + "params": MappingProxyType({"Message": "Hi"}), + "code": 400, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "__type": "aws.protocoltests.json10#InvalidGreeting",\n "Message": "Hi"\n}', + "bodyMediaType": "application/json", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="client"), + ], + members={"Message": {"target": STRING}}, +) + +GREETING_WITH_ERRORS = Schema( + id=ShapeID("aws.protocoltests.json10#GreetingWithErrors"), + shape_type=ShapeType.OPERATION, + traits=[Trait.new(id=ShapeID("smithy.api#idempotent"))], +) + +HOST_WITH_PATH_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#HostWithPathOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +HOST_WITH_PATH_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#HostWithPathOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HOST_WITH_PATH_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json10#HostWithPathOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10HostWithPath", + "documentation": "Custom endpoints supplied by users can have paths", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/custom/", + "body": "{}", + "host": "example.com/custom", + "appliesTo": "client", + } + ), + ), + ) + ], +) + +FOO_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnum"), + shape_type=ShapeType.ENUM, + members={ + "FOO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Foo")], + }, + "BAZ": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Baz")], + }, + "BAR": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Bar")], + }, + "ONE": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="1")], + }, + "ZERO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="0")], + }, + }, +) + +INTEGER_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnum"), + shape_type=ShapeType.INT_ENUM, + traits=[Trait.new(id=ShapeID("smithy.api#box"))], + members={ + "A": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=1)], + }, + "B": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=2)], + }, + "C": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=3)], + }, + }, +) + +STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING}}, +) + +STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +GREETING_STRUCT = Schema.collection( + id=ShapeID("aws.protocoltests.shared#GreetingStruct"), + members={"hi": {"target": STRING}}, +) + +MY_UNION = Schema.collection( + id=ShapeID("aws.protocoltests.json10#MyUnion"), + shape_type=ShapeType.UNION, + members={ + "stringValue": {"target": STRING}, + "booleanValue": {"target": BOOLEAN}, + "numberValue": {"target": INTEGER}, + "blobValue": {"target": BLOB}, + "timestampValue": {"target": TIMESTAMP}, + "enumValue": {"target": FOO_ENUM}, + "intEnumValue": {"target": INTEGER_ENUM}, + "listValue": {"target": STRING_LIST}, + "mapValue": {"target": STRING_MAP}, + "structureValue": {"target": GREETING_STRUCT}, + }, +) + +JSON_UNIONS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#JsonUnionsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"contents": {"target": MY_UNION}}, +) + +JSON_UNIONS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#JsonUnionsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"contents": {"target": MY_UNION}}, +) + +JSON_UNIONS = Schema( + id=ShapeID("aws.protocoltests.json10#JsonUnions"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10SerializeStringUnionValue", + "documentation": "Serializes a string union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "stringValue": "foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"stringValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SerializeBooleanUnionValue", + "documentation": "Serializes a boolean union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "booleanValue": true\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"booleanValue": True})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SerializeNumberUnionValue", + "documentation": "Serializes a number union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "numberValue": 1\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"numberValue": 1})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SerializeBlobUnionValue", + "documentation": "Serializes a blob union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "blobValue": "Zm9v"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"blobValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SerializeTimestampUnionValue", + "documentation": "Serializes a timestamp union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "timestampValue": 1398796238\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"timestampValue": 1398796238} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SerializeEnumUnionValue", + "documentation": "Serializes an enum union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "enumValue": "Foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"enumValue": "Foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SerializeIntEnumUnionValue", + "documentation": "Serializes an intEnum union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "intEnumValue": 1\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"intEnumValue": 1})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SerializeListUnionValue", + "documentation": "Serializes a list union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"listValue": ("foo", "bar")} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SerializeMapUnionValue", + "documentation": "Serializes a map union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "mapValue": MappingProxyType( + {"foo": "bar", "spam": "eggs"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SerializeStructureUnionValue", + "documentation": "Serializes a structure union value", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.JsonUnions", + } + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10DeserializeStringUnionValue", + "documentation": "Deserializes a string union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "stringValue": "foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"stringValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeBooleanUnionValue", + "documentation": "Deserializes a boolean union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "booleanValue": true\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"booleanValue": True})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeNumberUnionValue", + "documentation": "Deserializes a number union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "numberValue": 1\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"numberValue": 1})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeBlobUnionValue", + "documentation": "Deserializes a blob union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "blobValue": "Zm9v"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"blobValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeTimestampUnionValue", + "documentation": "Deserializes a timestamp union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "timestampValue": 1398796238\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"timestampValue": 1398796238} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeEnumUnionValue", + "documentation": "Deserializes an enum union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "enumValue": "Foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"enumValue": "Foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeIntEnumUnionValue", + "documentation": "Deserializes an intEnum union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "intEnumValue": 1\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"intEnumValue": 1})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeListUnionValue", + "documentation": "Deserializes a list union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"listValue": ("foo", "bar")} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeMapUnionValue", + "documentation": "Deserializes a map union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "mapValue": MappingProxyType( + {"foo": "bar", "spam": "eggs"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeStructureUnionValue", + "documentation": "Deserializes a structure union value", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeIgnoreType", + "appliesTo": "client", + "documentation": "Ignores an unrecognized __type property", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "__type": "aws.protocoltests.json10#MyUnion",\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10DeserializeAllowNulls", + "appliesTo": "client", + "documentation": "Allows for `: null` to be set for all unset fields", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "contents": {\n "stringValue": null,\n "booleanValue": null,\n "numberValue": null,\n "blobValue": null,\n "timestampValue": null,\n "enumValue": null,\n "intEnumValue": null,\n "listValue": null,\n "mapValue": null,\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + ), + ), + ], +) + +NO_INPUT_AND_NO_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#NoInputAndNoOutputInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +NO_INPUT_AND_NO_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#NoInputAndNoOutputOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +NO_INPUT_AND_NO_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.json10#NoInputAndNoOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10MustAlwaysSendEmptyJsonPayload", + "documentation": "Clients must always send an empty JSON object payload for\noperations with no input (that is, `{}`). While AWS service\nimplementations support requests with no payload or requests\nthat send `{}`, always sending `{}` from the client is\npreferred for forward compatibility in case input is ever\nadded to an operation.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.NoInputAndNoOutput", + } + ), + "uri": "/", + "body": "{}", + "bodyMediaType": "application/json", + } + ), + MappingProxyType( + { + "id": "AwsJson10ServiceSupportsNoPayloadForNoInput", + "documentation": "Service implementations must support no payload or an empty\nobject payload for operations that define no input. However,\ndespite the lack of a payload, a Content-Type header is still\nrequired in order for the service to properly detect the\nprotocol.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.NoInputAndNoOutput", + } + ), + "uri": "/", + "body": "", + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10HandlesEmptyOutputShape", + "protocol": "aws.protocols#awsJson1_0", + "documentation": "When no output is defined, the service is expected to return\nan empty payload, however, client must ignore a JSON payload\nif one is returned. This ensures that if output is added later,\nthen it will not break the client.", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "code": 200, + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10HandlesUnexpectedJsonOutput", + "protocol": "aws.protocols#awsJson1_0", + "documentation": "This client-only test builds on handles_empty_output_shape,\nby including unexpected fields in the JSON. A client\nneeds to ignore JSON output that is empty or that contains\nJSON object data.", + "body": '{\n "foo": true\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "code": 200, + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson10ServiceRespondsWithNoPayload", + "protocol": "aws.protocols#awsJson1_0", + "documentation": "When no output is defined, the service is expected to return\nan empty payload. Despite the lack of a payload, the service\nis expected to always send a Content-Type header. Clients must\nhandle cases where a service returns a JSON object and where\na service returns no JSON at all.", + "body": "", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "code": 200, + } + ), + ), + ), + ], +) + +NO_INPUT_AND_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#NoInputAndOutputInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +NO_INPUT_AND_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#NoInputAndOutputOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], +) + +NO_INPUT_AND_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.json10#NoInputAndOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10NoInputAndOutput", + "documentation": "A client should always send and empty JSON object payload.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.NoInputAndOutput", + } + ), + "uri": "/", + "body": "{}", + "bodyMediaType": "application/json", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10NoInputAndOutput", + "documentation": "Empty output always serializes an empty object payload.", + "protocol": "aws.protocols#awsJson1_0", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "code": 200, + "body": "{}", + "bodyMediaType": "application/json", + } + ), + ), + ), + ], +) + +OPERATION_WITH_DEFAULTS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#OperationWithDefaultsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "defaults": {"target": DEFAULTS}, + "clientOptionalDefaults": {"target": CLIENT_OPTIONAL_DEFAULTS}, + "topLevelDefault": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "otherTopLevelDefault": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + }, +) + +OPERATION_WITH_DEFAULTS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#OperationWithDefaultsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "defaultString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "defaultBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=True)], + }, + "defaultList": { + "target": TEST_STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "defaultDocumentMap": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + "defaultDocumentString": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "defaultDocumentBoolean": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=True)], + }, + "defaultDocumentList": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "defaultNullDocument": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=None)], + }, + "defaultTimestamp": { + "target": TIMESTAMP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "defaultBlob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="YWJj")], + }, + "defaultByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "defaultShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "defaultInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=10)], + }, + "defaultLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=100)], + }, + "defaultFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1.0)], + }, + "defaultDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1.0)], + }, + "defaultMap": { + "target": TEST_STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + "defaultEnum": { + "target": TEST_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="FOO")], + }, + "defaultIntEnum": { + "target": TEST_INT_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "emptyString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="")], + }, + "falseBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=False)], + }, + "emptyBlob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="")], + }, + "zeroByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0.0)], + }, + "zeroDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0.0)], + }, + }, +) + +OPERATION_WITH_DEFAULTS = Schema( + id=ShapeID("aws.protocoltests.json10#OperationWithDefaults"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10ClientPopulatesDefaultValuesInInput", + "documentation": "Client populates default values in input.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "defaults": {\n "defaultString": "hi",\n "defaultBoolean": true,\n "defaultList": [],\n "defaultDocumentMap": {},\n "defaultDocumentString": "hi",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": [],\n "defaultTimestamp": 0,\n "defaultBlob": "YWJj",\n "defaultByte": 1,\n "defaultShort": 1,\n "defaultInteger": 10,\n "defaultLong": 100,\n "defaultFloat": 1.0,\n "defaultDouble": 1.0,\n "defaultMap": {},\n "defaultEnum": "FOO",\n "defaultIntEnum": 1,\n "emptyString": "",\n "falseBoolean": false,\n "emptyBlob": "",\n "zeroByte": 0,\n "zeroShort": 0,\n "zeroInteger": 0,\n "zeroLong": 0,\n "zeroFloat": 0.0,\n "zeroDouble": 0.0\n }\n}', + "params": MappingProxyType({"defaults": MappingProxyType({})}), + } + ), + MappingProxyType( + { + "id": "AwsJson10ClientSkipsTopLevelDefaultValuesInInput", + "documentation": "Client skips top level default values in input.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": "{\n}", + "params": MappingProxyType({}), + } + ), + MappingProxyType( + { + "id": "AwsJson10ClientUsesExplicitlyProvidedMemberValuesOverDefaults", + "documentation": "Client uses explicitly provided member values over defaults", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + { + "defaults": MappingProxyType( + { + "defaultString": "bye", + "defaultBoolean": True, + "defaultList": ("a",), + "defaultDocumentMap": MappingProxyType( + {"name": "Jack"} + ), + "defaultDocumentString": "bye", + "defaultDocumentBoolean": True, + "defaultDocumentList": ("b",), + "defaultNullDocument": "notNull", + "defaultTimestamp": 1, + "defaultBlob": "hi", + "defaultByte": 2, + "defaultShort": 2, + "defaultInteger": 20, + "defaultLong": 200, + "defaultFloat": 2.0, + "defaultDouble": 2.0, + "defaultMap": MappingProxyType( + {"name": "Jack"} + ), + "defaultEnum": "BAR", + "defaultIntEnum": 2, + "emptyString": "foo", + "falseBoolean": True, + "emptyBlob": "hi", + "zeroByte": 1, + "zeroShort": 1, + "zeroInteger": 1, + "zeroLong": 1, + "zeroFloat": 1.0, + "zeroDouble": 1.0, + } + ) + } + ), + "body": '{\n "defaults": {\n "defaultString": "bye",\n "defaultBoolean": true,\n "defaultList": ["a"],\n "defaultDocumentMap": {"name": "Jack"},\n "defaultDocumentString": "bye",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": ["b"],\n "defaultNullDocument": "notNull",\n "defaultTimestamp": 1,\n "defaultBlob": "aGk=",\n "defaultByte": 2,\n "defaultShort": 2,\n "defaultInteger": 20,\n "defaultLong": 200,\n "defaultFloat": 2.0,\n "defaultDouble": 2.0,\n "defaultMap": {"name": "Jack"},\n "defaultEnum": "BAR",\n "defaultIntEnum": 2,\n "emptyString": "foo",\n "falseBoolean": true,\n "emptyBlob": "aGk=",\n "zeroByte": 1,\n "zeroShort": 1,\n "zeroInteger": 1,\n "zeroLong": 1,\n "zeroFloat": 1.0,\n "zeroDouble": 1.0\n }\n}', + } + ), + MappingProxyType( + { + "id": "AwsJson10ServerPopulatesDefaultsWhenMissingInRequestBody", + "documentation": "Server populates default values when missing in request body.", + "appliesTo": "server", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n"defaults": {}\n}', + "params": MappingProxyType( + { + "defaults": MappingProxyType( + { + "defaultString": "hi", + "defaultBoolean": True, + "defaultList": (), + "defaultDocumentMap": MappingProxyType({}), + "defaultDocumentString": "hi", + "defaultDocumentBoolean": True, + "defaultDocumentList": (), + "defaultTimestamp": 0, + "defaultBlob": "abc", + "defaultByte": 1, + "defaultShort": 1, + "defaultInteger": 10, + "defaultLong": 100, + "defaultFloat": 1.0, + "defaultDouble": 1.0, + "defaultMap": MappingProxyType({}), + "defaultEnum": "FOO", + "defaultIntEnum": 1, + "emptyString": "", + "falseBoolean": False, + "emptyBlob": "", + "zeroByte": 0, + "zeroShort": 0, + "zeroInteger": 0, + "zeroLong": 0, + "zeroFloat": 0.0, + "zeroDouble": 0.0, + } + ), + "topLevelDefault": "hi", + "otherTopLevelDefault": 0, + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10ClientUsesExplicitlyProvidedValuesInTopLevel", + "documentation": "Any time a value is provided for a member in the top level of input, it is used, regardless of if its the default.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "topLevelDefault": "hi",\n "otherTopLevelDefault": 0\n}', + "params": MappingProxyType( + {"topLevelDefault": "hi", "otherTopLevelDefault": 0} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10ClientIgnoresNonTopLevelDefaultsOnMembersWithClientOptional", + "documentation": "Typically, non top-level members would have defaults filled in, but if they have the clientOptional trait, the defaults should be ignored.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "clientOptionalDefaults": {}\n}', + "params": MappingProxyType( + {"clientOptionalDefaults": MappingProxyType({})} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10ClientPopulatesDefaultsValuesWhenMissingInResponse", + "documentation": "Client populates default values when missing in response.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": "{}", + "params": MappingProxyType( + { + "defaultString": "hi", + "defaultBoolean": True, + "defaultList": (), + "defaultDocumentMap": MappingProxyType({}), + "defaultDocumentString": "hi", + "defaultDocumentBoolean": True, + "defaultDocumentList": (), + "defaultTimestamp": 0, + "defaultBlob": "abc", + "defaultByte": 1, + "defaultShort": 1, + "defaultInteger": 10, + "defaultLong": 100, + "defaultFloat": 1.0, + "defaultDouble": 1.0, + "defaultMap": MappingProxyType({}), + "defaultEnum": "FOO", + "defaultIntEnum": 1, + "emptyString": "", + "falseBoolean": False, + "emptyBlob": "", + "zeroByte": 0, + "zeroShort": 0, + "zeroInteger": 0, + "zeroLong": 0, + "zeroFloat": 0.0, + "zeroDouble": 0.0, + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10ClientIgnoresDefaultValuesIfMemberValuesArePresentInResponse", + "documentation": "Client ignores default values if member values are present in the response.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "defaultString": "bye",\n "defaultBoolean": false,\n "defaultList": ["a"],\n "defaultDocumentMap": {"name": "Jack"},\n "defaultDocumentString": "bye",\n "defaultDocumentBoolean": false,\n "defaultDocumentList": ["b"],\n "defaultNullDocument": "notNull",\n "defaultTimestamp": 2,\n "defaultBlob": "aGk=",\n "defaultByte": 2,\n "defaultShort": 2,\n "defaultInteger": 20,\n "defaultLong": 200,\n "defaultFloat": 2.0,\n "defaultDouble": 2.0,\n "defaultMap": {"name": "Jack"},\n "defaultEnum": "BAR",\n "defaultIntEnum": 2,\n "emptyString": "foo",\n "falseBoolean": true,\n "emptyBlob": "aGk=",\n "zeroByte": 1,\n "zeroShort": 1,\n "zeroInteger": 1,\n "zeroLong": 1,\n "zeroFloat": 1.0,\n "zeroDouble": 1.0\n}', + "params": MappingProxyType( + { + "defaultString": "bye", + "defaultBoolean": False, + "defaultList": ("a",), + "defaultDocumentMap": MappingProxyType( + {"name": "Jack"} + ), + "defaultDocumentString": "bye", + "defaultDocumentBoolean": False, + "defaultDocumentList": ("b",), + "defaultNullDocument": "notNull", + "defaultTimestamp": 2, + "defaultBlob": "hi", + "defaultByte": 2, + "defaultShort": 2, + "defaultInteger": 20, + "defaultLong": 200, + "defaultFloat": 2.0, + "defaultDouble": 2.0, + "defaultMap": MappingProxyType({"name": "Jack"}), + "defaultEnum": "BAR", + "defaultIntEnum": 2, + "emptyString": "foo", + "falseBoolean": True, + "emptyBlob": "hi", + "zeroByte": 1, + "zeroShort": 1, + "zeroInteger": 1, + "zeroLong": 1, + "zeroFloat": 1.0, + "zeroDouble": 1.0, + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10ServerPopulatesDefaultsInResponseWhenMissingInParams", + "documentation": "Server populates default values in response when missing in params.", + "appliesTo": "server", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "defaultString": "hi",\n "defaultBoolean": true,\n "defaultList": [],\n "defaultDocumentMap": {},\n "defaultDocumentString": "hi",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": [],\n "defaultTimestamp": 0,\n "defaultBlob": "YWJj",\n "defaultByte": 1,\n "defaultShort": 1,\n "defaultInteger": 10,\n "defaultLong": 100,\n "defaultFloat": 1.0,\n "defaultDouble": 1.0,\n "defaultMap": {},\n "defaultEnum": "FOO",\n "defaultIntEnum": 1,\n "emptyString": "",\n "falseBoolean": false,\n "emptyBlob": "",\n "zeroByte": 0,\n "zeroShort": 0,\n "zeroInteger": 0,\n "zeroLong": 0,\n "zeroFloat": 0.0,\n "zeroDouble": 0.0\n}', + "params": MappingProxyType({}), + } + ), + ), + ), + ], +) + +TOP_LEVEL = Schema.collection( + id=ShapeID("aws.protocoltests.json10#TopLevel"), + members={ + "dialog": { + "target": DIALOG, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "dialogList": { + "target": DIALOG_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "dialogMap": { + "target": DIALOG_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + }, +) + +OPERATION_WITH_NESTED_STRUCTURE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#OperationWithNestedStructureInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "topLevel": { + "target": TOP_LEVEL, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + } + }, +) + +OPERATION_WITH_NESTED_STRUCTURE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#OperationWithNestedStructureOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "dialog": { + "target": DIALOG, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "dialogList": { + "target": DIALOG_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "dialogMap": { + "target": DIALOG_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + }, +) + +OPERATION_WITH_NESTED_STRUCTURE = Schema( + id=ShapeID("aws.protocoltests.json10#OperationWithNestedStructure"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10ClientPopulatesNestedDefaultValuesWhenMissing", + "documentation": "Client populates nested default values when missing.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "topLevel": {\n "dialog": {\n "language": "en",\n "greeting": "hi"\n },\n "dialogList": [\n {\n "greeting": "hi"\n },\n {\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n "greeting": "hi"\n },\n "partialEmptyDialog": {\n "language": "en",\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n }\n}', + "params": MappingProxyType( + { + "topLevel": MappingProxyType( + { + "dialog": MappingProxyType({"language": "en"}), + "dialogList": ( + MappingProxyType({}), + MappingProxyType( + {"farewell": MappingProxyType({})} + ), + MappingProxyType( + { + "language": "it", + "greeting": "ciao", + "farewell": MappingProxyType( + {"phrase": "arrivederci"} + ), + } + ), + ), + "dialogMap": MappingProxyType( + { + "emptyDialog": MappingProxyType({}), + "partialEmptyDialog": MappingProxyType( + { + "language": "en", + "farewell": MappingProxyType( + {} + ), + } + ), + "nonEmptyDialog": MappingProxyType( + { + "greeting": "konnichiwa", + "farewell": MappingProxyType( + {"phrase": "sayonara"} + ), + } + ), + } + ), + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10ServerPopulatesNestedDefaultsWhenMissingInRequestBody", + "documentation": "Server populates nested default values when missing in request body.", + "appliesTo": "server", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "topLevel": {\n "dialog": {\n "language": "en"\n },\n "dialogList": [\n {\n },\n {\n "farewell": {}\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n },\n "partialEmptyDialog": {\n "language": "en",\n "farewell": {}\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n }\n}', + "params": MappingProxyType( + { + "topLevel": MappingProxyType( + { + "dialog": MappingProxyType( + {"language": "en", "greeting": "hi"} + ), + "dialogList": ( + MappingProxyType({"greeting": "hi"}), + MappingProxyType( + { + "greeting": "hi", + "farewell": MappingProxyType( + {"phrase": "bye"} + ), + } + ), + MappingProxyType( + { + "language": "it", + "greeting": "ciao", + "farewell": MappingProxyType( + {"phrase": "arrivederci"} + ), + } + ), + ), + "dialogMap": MappingProxyType( + { + "emptyDialog": MappingProxyType( + {"greeting": "hi"} + ), + "partialEmptyDialog": MappingProxyType( + { + "language": "en", + "greeting": "hi", + "farewell": MappingProxyType( + {"phrase": "bye"} + ), + } + ), + "nonEmptyDialog": MappingProxyType( + { + "greeting": "konnichiwa", + "farewell": MappingProxyType( + {"phrase": "sayonara"} + ), + } + ), + } + ), + } + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10ClientPopulatesNestedDefaultsWhenMissingInResponseBody", + "documentation": "Client populates nested default values when missing in response body.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "dialog": {\n "language": "en"\n },\n "dialogList": [\n {\n },\n {\n "farewell": {}\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n },\n "partialEmptyDialog": {\n "language": "en",\n "farewell": {}\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n}', + "params": MappingProxyType( + { + "dialog": MappingProxyType( + {"language": "en", "greeting": "hi"} + ), + "dialogList": ( + MappingProxyType({"greeting": "hi"}), + MappingProxyType( + { + "greeting": "hi", + "farewell": MappingProxyType( + {"phrase": "bye"} + ), + } + ), + MappingProxyType( + { + "language": "it", + "greeting": "ciao", + "farewell": MappingProxyType( + {"phrase": "arrivederci"} + ), + } + ), + ), + "dialogMap": MappingProxyType( + { + "emptyDialog": MappingProxyType( + {"greeting": "hi"} + ), + "partialEmptyDialog": MappingProxyType( + { + "language": "en", + "greeting": "hi", + "farewell": MappingProxyType( + {"phrase": "bye"} + ), + } + ), + "nonEmptyDialog": MappingProxyType( + { + "greeting": "konnichiwa", + "farewell": MappingProxyType( + {"phrase": "sayonara"} + ), + } + ), + } + ), + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10ServerPopulatesNestedDefaultValuesWhenMissingInInResponseParams", + "documentation": "Server populates nested default values when missing in response params.", + "appliesTo": "server", + "tags": ("defaults",), + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": '{\n "dialog": {\n "language": "en",\n "greeting": "hi"\n },\n "dialogList": [\n {\n "greeting": "hi"\n },\n {\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n "greeting": "hi"\n },\n "partialEmptyDialog": {\n "language": "en",\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n}', + "params": MappingProxyType( + { + "dialog": MappingProxyType({"language": "en"}), + "dialogList": ( + MappingProxyType({}), + MappingProxyType( + {"farewell": MappingProxyType({})} + ), + MappingProxyType( + { + "language": "it", + "greeting": "ciao", + "farewell": MappingProxyType( + {"phrase": "arrivederci"} + ), + } + ), + ), + "dialogMap": MappingProxyType( + { + "emptyDialog": MappingProxyType({}), + "partialEmptyDialog": MappingProxyType( + { + "language": "en", + "farewell": MappingProxyType({}), + } + ), + "nonEmptyDialog": MappingProxyType( + { + "greeting": "konnichiwa", + "farewell": MappingProxyType( + {"phrase": "sayonara"} + ), + } + ), + } + ), + } + ), + } + ), + ), + ), + ], +) + +OPERATION_WITH_REQUIRED_MEMBERS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#OperationWithRequiredMembersInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +REQUIRED_STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.json10#RequiredStringList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING}}, +) + +REQUIRED_STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.json10#RequiredStringMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#OperationWithRequiredMembersOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "requiredString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredList": { + "target": REQUIRED_STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredTimestamp": { + "target": TIMESTAMP, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredBlob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "requiredMap": { + "target": REQUIRED_STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + }, +) + +OPERATION_WITH_REQUIRED_MEMBERS = Schema( + id=ShapeID("aws.protocoltests.json10#OperationWithRequiredMembers"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10ClientErrorCorrectsWhenServerFailsToSerializeRequiredValues", + "documentation": "Client error corrects when server fails to serialize required values.", + "appliesTo": "client", + "tags": ("defaults", "error-correction"), + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": "{}", + "params": MappingProxyType( + { + "requiredString": "", + "requiredBoolean": False, + "requiredList": (), + "requiredTimestamp": 0, + "requiredBlob": "", + "requiredByte": 0, + "requiredShort": 0, + "requiredInteger": 0, + "requiredLong": 0, + "requiredFloat": 0.0, + "requiredDouble": 0.0, + "requiredMap": MappingProxyType({}), + } + ), + } + ), + ), + ) + ], +) + +OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_INPUT = Schema.collection( + id=ShapeID( + "aws.protocoltests.json10#OperationWithRequiredMembersWithDefaultsInput" + ), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +REQUIRED_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.json10#RequiredEnum"), + shape_type=ShapeType.ENUM, + members={ + "FOO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="FOO")], + }, + "BAR": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="BAR")], + }, + "BAZ": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="BAZ")], + }, + }, +) + +REQUIRED_INT_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.json10#RequiredIntEnum"), + shape_type=ShapeType.INT_ENUM, + traits=[Trait.new(id=ShapeID("smithy.api#box"))], + members={ + "ONE": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=1)], + }, + "TWO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=2)], + }, + }, +) + +OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT = Schema.collection( + id=ShapeID( + "aws.protocoltests.json10#OperationWithRequiredMembersWithDefaultsOutput" + ), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "requiredString": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value="hi"), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredBoolean": { + "target": BOOLEAN, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=True), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredList": { + "target": REQUIRED_STRING_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=()), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredTimestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=1), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredBlob": { + "target": BLOB, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value="YmxvYg=="), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredByte": { + "target": BYTE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=1), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredShort": { + "target": SHORT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=1), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredInteger": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=10), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredLong": { + "target": LONG, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=100), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredFloat": { + "target": FLOAT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=1.0), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredDouble": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=1.0), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredMap": { + "target": REQUIRED_STRING_MAP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default")), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredEnum": { + "target": REQUIRED_ENUM, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value="FOO"), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "requiredIntEnum": { + "target": REQUIRED_INT_ENUM, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=1), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + }, +) + +OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS = Schema( + id=ShapeID("aws.protocoltests.json10#OperationWithRequiredMembersWithDefaults"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10ClientErrorCorrectsWithDefaultValuesWhenServerFailsToSerializeRequiredValues", + "documentation": "Client error corrects with default values when server fails to serialize required values.", + "appliesTo": "client", + "tags": ("defaults", "error-correction"), + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "body": "{}", + "params": MappingProxyType( + { + "requiredString": "hi", + "requiredBoolean": True, + "requiredList": (), + "requiredTimestamp": 1, + "requiredBlob": "blob", + "requiredByte": 1, + "requiredShort": 1, + "requiredInteger": 10, + "requiredLong": 100, + "requiredFloat": 1.0, + "requiredDouble": 1.0, + "requiredMap": MappingProxyType({}), + "requiredEnum": "FOO", + "requiredIntEnum": 1, + } + ), + } + ), + ), + ) + ], +) + +PUT_WITH_CONTENT_ENCODING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#PutWithContentEncodingInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "encoding": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="Content-Encoding") + ], + }, + "data": {"target": STRING}, + }, +) + +PUT_WITH_CONTENT_ENCODING_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#PutWithContentEncodingOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +PUT_WITH_CONTENT_ENCODING = Schema( + id=ShapeID("aws.protocoltests.json10#PutWithContentEncoding"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "SDKAppliedContentEncoding_awsJson1_0", + "documentation": "Compression algorithm encoding is appended to the Content-Encoding header.", + "protocol": "aws.protocols#awsJson1_0", + "params": MappingProxyType( + { + "data": "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\n" + } + ), + "method": "POST", + "uri": "/", + "headers": MappingProxyType({"Content-Encoding": "gzip"}), + } + ), + MappingProxyType( + { + "id": "SDKAppendsGzipAndIgnoresHttpProvidedEncoding_awsJson1_0", + "documentation": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is NOT in the Content-Encoding header since HTTP binding\ntraits are ignored in the awsJson1_0 protocol.\n", + "protocol": "aws.protocols#awsJson1_0", + "params": MappingProxyType( + { + "encoding": "custom", + "data": "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\n", + } + ), + "method": "POST", + "uri": "/", + "headers": MappingProxyType({"Content-Encoding": "gzip"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#requestCompression"), + value=MappingProxyType({"encodings": ("gzip",)}), + ), + ], +) + +QUERY_INCOMPATIBLE_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#QueryIncompatibleOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +QUERY_INCOMPATIBLE_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#QueryIncompatibleOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +QUERY_INCOMPATIBLE_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json10#QueryIncompatibleOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "NonQueryCompatibleAwsJson10ForbidsQueryModeHeader", + "documentation": "The query mode header MUST NOT be set on non-query-compatible services.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.QueryIncompatibleOperation", + } + ), + "uri": "/", + "body": "{}", + "bodyMediaType": "application/json", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + ], +) + +SIMPLE_SCALAR_PROPERTIES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#SimpleScalarPropertiesInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"floatValue": {"target": FLOAT}, "doubleValue": {"target": DOUBLE}}, +) + +SIMPLE_SCALAR_PROPERTIES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json10#SimpleScalarPropertiesOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"floatValue": {"target": FLOAT}, "doubleValue": {"target": DOUBLE}}, +) + +SIMPLE_SCALAR_PROPERTIES = Schema( + id=ShapeID("aws.protocoltests.json10#SimpleScalarProperties"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10SupportsNaNFloatInputs", + "documentation": "Supports handling NaN float values.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "floatValue": "NaN",\n "doubleValue": "NaN"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.SimpleScalarProperties", + } + ), + "params": MappingProxyType( + {"floatValue": "NaN", "doubleValue": "NaN"} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SupportsInfinityFloatInputs", + "documentation": "Supports handling Infinity float values.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "floatValue": "Infinity",\n "doubleValue": "Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.SimpleScalarProperties", + } + ), + "params": MappingProxyType( + {"floatValue": "Infinity", "doubleValue": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SupportsNegativeInfinityFloatInputs", + "documentation": "Supports handling -Infinity float values.", + "protocol": "aws.protocols#awsJson1_0", + "method": "POST", + "uri": "/", + "body": '{\n "floatValue": "-Infinity",\n "doubleValue": "-Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.0", + "X-Amz-Target": "JsonRpc10.SimpleScalarProperties", + } + ), + "params": MappingProxyType( + {"floatValue": "-Infinity", "doubleValue": "-Infinity"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson10SupportsNaNFloatInputs", + "documentation": "Supports handling NaN float values.", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "floatValue": "NaN",\n "doubleValue": "NaN"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + {"floatValue": "NaN", "doubleValue": "NaN"} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SupportsInfinityFloatInputs", + "documentation": "Supports handling Infinity float values.", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "floatValue": "Infinity",\n "doubleValue": "Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + {"floatValue": "Infinity", "doubleValue": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson10SupportsNegativeInfinityFloatInputs", + "documentation": "Supports handling -Infinity float values.", + "protocol": "aws.protocols#awsJson1_0", + "code": 200, + "body": '{\n "floatValue": "-Infinity",\n "doubleValue": "-Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.0"} + ), + "params": MappingProxyType( + {"floatValue": "-Infinity", "doubleValue": "-Infinity"} + ), + } + ), + ), + ), + ], +) + +JSON_RPC10 = Schema( + id=ShapeID("aws.protocoltests.json10#JsonRpc10"), + shape_type=ShapeType.SERVICE, + traits=[ + Trait.new( + id=ShapeID("aws.auth#sigv4"), value=MappingProxyType({"name": "jsonrpc10"}) + ), + Trait.new( + id=ShapeID("smithy.api#title"), value="Sample Json 1.0 Protocol Service" + ), + Trait.new(id=ShapeID("aws.protocols#awsJson1_0")), + Trait.new( + id=ShapeID("aws.api#service"), + value=MappingProxyType({"sdkId": "JSON RPC 10"}), + ), + ], +) diff --git a/codegen-output/aws-json-1-0/src/awsjson10/auth.py b/codegen-output/aws-json-1-0/src/awsjson10/auth.py new file mode 100644 index 000000000..24ca90fec --- /dev/null +++ b/codegen-output/aws-json-1-0/src/awsjson10/auth.py @@ -0,0 +1,31 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from typing import Any + +from smithy_core.auth import AuthOption as _smithy_core_auth_AuthOption, AuthParams +from smithy_core.interfaces.auth import ( + AuthOption as _smithy_core_interfaces_auth_AuthOption, +) +from smithy_core.shapes import ShapeID + + +class HTTPAuthSchemeResolver: + def resolve_auth_scheme( + self, auth_parameters: AuthParams[Any, Any] + ) -> list[_smithy_core_interfaces_auth_AuthOption]: + auth_options: list[_smithy_core_interfaces_auth_AuthOption] = [] + + if (option := _generate_sigv4_option(auth_parameters)) is not None: + auth_options.append(option) + + return auth_options + + +def _generate_sigv4_option( + auth_params: AuthParams[Any, Any], +) -> _smithy_core_interfaces_auth_AuthOption | None: + return _smithy_core_auth_AuthOption( + scheme_id=ShapeID("aws.auth#sigv4"), + identity_properties={}, # type: ignore + signer_properties={}, # type: ignore + ) diff --git a/codegen-output/aws-json-1-0/src/awsjson10/client.py b/codegen-output/aws-json-1-0/src/awsjson10/client.py new file mode 100644 index 000000000..eaa6bce45 --- /dev/null +++ b/codegen-output/aws-json-1-0/src/awsjson10/client.py @@ -0,0 +1,1254 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +import asyncio +from copy import deepcopy +import logging +from typing import Any, Self, cast + +from smithy_aws_core.config import ConfigSource +from smithy_aws_core.identity import AWSCredentialsIdentity +from smithy_aws_core.identity.chain import IdentityChain +from smithy_core.aio.client import ClientCall, RequestPipeline +from smithy_core.aio.retries import RetryStrategyResolver +from smithy_core.aio.utils import close +from smithy_core.exceptions import ExpectationNotMetError +from smithy_core.interceptors import InterceptorChain +from smithy_core.types import TypedProperties +from smithy_http.aio.interfaces import HTTPClient +from smithy_http.plugins import user_agent_plugin + +from .config import AsyncJSONRPC10Config, Plugin +from .models import ( + CONTENT_TYPE_PARAMETERS, + ContentTypeParametersInput, + ContentTypeParametersOutput, + EMPTY_INPUT_AND_EMPTY_OUTPUT, + ENDPOINT_OPERATION, + ENDPOINT_WITH_HOST_LABEL_OPERATION, + EmptyInputAndEmptyOutputInput, + EmptyInputAndEmptyOutputOutput, + EndpointOperationInput, + EndpointOperationOutput, + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + GREETING_WITH_ERRORS, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HOST_WITH_PATH_OPERATION, + HostWithPathOperationInput, + HostWithPathOperationOutput, + JSON_UNIONS, + JsonUnionsInput, + JsonUnionsOutput, + NO_INPUT_AND_NO_OUTPUT, + NO_INPUT_AND_OUTPUT, + NoInputAndNoOutputInput, + NoInputAndNoOutputOutput, + NoInputAndOutputInput, + NoInputAndOutputOutput, + OPERATION_WITH_DEFAULTS, + OPERATION_WITH_NESTED_STRUCTURE, + OPERATION_WITH_REQUIRED_MEMBERS, + OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS, + OperationWithDefaultsInput, + OperationWithDefaultsOutput, + OperationWithNestedStructureInput, + OperationWithNestedStructureOutput, + OperationWithRequiredMembersInput, + OperationWithRequiredMembersOutput, + OperationWithRequiredMembersWithDefaultsInput, + OperationWithRequiredMembersWithDefaultsOutput, + PUT_WITH_CONTENT_ENCODING, + PutWithContentEncodingInput, + PutWithContentEncodingOutput, + QUERY_INCOMPATIBLE_OPERATION, + QueryIncompatibleOperationInput, + QueryIncompatibleOperationOutput, + SIMPLE_SCALAR_PROPERTIES, + SimpleScalarPropertiesInput, + SimpleScalarPropertiesOutput, +) +from .user_agent import aws_user_agent_plugin + + +logger = logging.getLogger(__name__) + + +class AsyncJSONRPC10Client: + """Client for JsonRpc10""" + + def __init__( + self, + config: AsyncJSONRPC10Config | None = None, + plugins: list[Plugin] | None = None, + ): + """ + Constructor for `AsyncJSONRPC10Client`. + + Args: + config: + Optional configuration for the client. Here you can set things like + the endpoint for HTTP services or auth credentials. + plugins: + A list of callables applied once to the client's base configuration. + Their changes are inherited by every operation invocation. + """ + self._config = config + self._plugins = plugins + self._derive_lock = asyncio.Lock() + self._setup_done = False + self._closed = False + self._retry_strategy_resolver = RetryStrategyResolver() + self._client_plugins: list[Plugin] = [aws_user_agent_plugin, user_agent_plugin] + + async def _ensure_setup(self) -> None: + if not self._setup_done: + async with self._derive_lock: + if not self._setup_done: + if self._config is None: + config = await AsyncJSONRPC10Config.resolve() + else: + # Copy so plugins don't mutate the caller's config. + config = deepcopy(self._config) + for plugin in self._client_plugins: + plugin(config) + if self._plugins: + for plugin in self._plugins: + plugin(config) + self._config = config + + if self._config.aws_credentials_identity_resolver is None: + config_context = self._config.resolution_context() + config_file = None + profile_name = None + if config_context is not None: + config_file = await config_context.parsed_profiles() + if config_context.profile_source is ConfigSource.OVERRIDE: + profile_name = config_context.profile_name + self._config.aws_credentials_identity_resolver = ( + await IdentityChain.create( + AWSCredentialsIdentity, + config_file=config_file, + profile_name=profile_name, + region_override=self._config.region, + http_client=cast( + HTTPClient | None, self._config.transport + ), + ) + ) + self._setup_done = True + + async def close(self) -> None: + """Close this client and any resources held by its transport.""" + if self._closed: + return + async with self._derive_lock: + if self._closed: + return + self._closed = True + if self._setup_done and self._config is not None: + await close(self._config.transport) + + async def __aenter__(self) -> Self: + if self._closed: + raise RuntimeError("Cannot enter a client that has been closed.") + return self + + async def __aexit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: + await self.close() + + async def content_type_parameters( + self, input: ContentTypeParametersInput, plugins: list[Plugin] | None = None + ) -> ContentTypeParametersOutput: + """ + The example tests how servers must support requests containing a + `Content-Type` header with parameters. + + Args: + input: + An instance of `ContentTypeParametersInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `ContentTypeParametersOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=CONTENT_TYPE_PARAMETERS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def empty_input_and_empty_output( + self, input: EmptyInputAndEmptyOutputInput, plugins: list[Plugin] | None = None + ) -> EmptyInputAndEmptyOutputOutput: + """ + The example tests how requests and responses are serialized when + there's no request or response payload because the operation has an + empty input and empty output structure that reuses the same shape. While + this should be rare, code generators must support this. + + Args: + input: + An instance of `EmptyInputAndEmptyOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EmptyInputAndEmptyOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=EMPTY_INPUT_AND_EMPTY_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def endpoint_operation( + self, input: EndpointOperationInput, plugins: list[Plugin] | None = None + ) -> EndpointOperationOutput: + """ + Invokes the EndpointOperation operation. + + Args: + input: + An instance of `EndpointOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EndpointOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=ENDPOINT_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def endpoint_with_host_label_operation( + self, + input: EndpointWithHostLabelOperationInput, + plugins: list[Plugin] | None = None, + ) -> EndpointWithHostLabelOperationOutput: + """ + Invokes the EndpointWithHostLabelOperation operation. + + Args: + input: + An instance of `EndpointWithHostLabelOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EndpointWithHostLabelOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=ENDPOINT_WITH_HOST_LABEL_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def greeting_with_errors( + self, input: GreetingWithErrorsInput, plugins: list[Plugin] | None = None + ) -> GreetingWithErrorsOutput: + """ + This operation has three possible return values: 1. A successful + response in the form of GreetingWithErrorsOutput 2. An InvalidGreeting + error. 3. A ComplexError error. Implementations must be able to + successfully take a response and properly deserialize successful and + error responses. + + Args: + input: + An instance of `GreetingWithErrorsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `GreetingWithErrorsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=GREETING_WITH_ERRORS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def host_with_path_operation( + self, input: HostWithPathOperationInput, plugins: list[Plugin] | None = None + ) -> HostWithPathOperationOutput: + """ + Invokes the HostWithPathOperation operation. + + Args: + input: + An instance of `HostWithPathOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HostWithPathOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HOST_WITH_PATH_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_unions( + self, input: JsonUnionsInput, plugins: list[Plugin] | None = None + ) -> JsonUnionsOutput: + """ + This operation uses unions for inputs and outputs. + + Args: + input: + An instance of `JsonUnionsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonUnionsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_UNIONS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def no_input_and_no_output( + self, input: NoInputAndNoOutputInput, plugins: list[Plugin] | None = None + ) -> NoInputAndNoOutputOutput: + """ + The example tests how requests and responses are serialized when + there's no request or response payload because the operation has no + input or output. While this should be rare, code generators must support + this. + + Args: + input: + An instance of `NoInputAndNoOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NoInputAndNoOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NO_INPUT_AND_NO_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def no_input_and_output( + self, input: NoInputAndOutputInput, plugins: list[Plugin] | None = None + ) -> NoInputAndOutputOutput: + """ + The example tests how requests and responses are serialized when + there's no request or response payload because the operation has no + input and the output is empty. While this should be rare, code + generators must support this. + + Args: + input: + An instance of `NoInputAndOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NoInputAndOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NO_INPUT_AND_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def operation_with_defaults( + self, input: OperationWithDefaultsInput, plugins: list[Plugin] | None = None + ) -> OperationWithDefaultsOutput: + """ + Invokes the OperationWithDefaults operation. + + Args: + input: + An instance of `OperationWithDefaultsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `OperationWithDefaultsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OPERATION_WITH_DEFAULTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def operation_with_nested_structure( + self, + input: OperationWithNestedStructureInput, + plugins: list[Plugin] | None = None, + ) -> OperationWithNestedStructureOutput: + """ + Invokes the OperationWithNestedStructure operation. + + Args: + input: + An instance of `OperationWithNestedStructureInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `OperationWithNestedStructureOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OPERATION_WITH_NESTED_STRUCTURE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def operation_with_required_members( + self, + input: OperationWithRequiredMembersInput, + plugins: list[Plugin] | None = None, + ) -> OperationWithRequiredMembersOutput: + """ + Invokes the OperationWithRequiredMembers operation. + + Args: + input: + An instance of `OperationWithRequiredMembersInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `OperationWithRequiredMembersOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OPERATION_WITH_REQUIRED_MEMBERS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def operation_with_required_members_with_defaults( + self, + input: OperationWithRequiredMembersWithDefaultsInput, + plugins: list[Plugin] | None = None, + ) -> OperationWithRequiredMembersWithDefaultsOutput: + """ + Invokes the OperationWithRequiredMembersWithDefaults operation. + + Args: + input: + An instance of `OperationWithRequiredMembersWithDefaultsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `OperationWithRequiredMembersWithDefaultsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def put_with_content_encoding( + self, input: PutWithContentEncodingInput, plugins: list[Plugin] | None = None + ) -> PutWithContentEncodingOutput: + """ + Invokes the PutWithContentEncoding operation. + + Args: + input: + An instance of `PutWithContentEncodingInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `PutWithContentEncodingOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=PUT_WITH_CONTENT_ENCODING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def query_incompatible_operation( + self, + input: QueryIncompatibleOperationInput, + plugins: list[Plugin] | None = None, + ) -> QueryIncompatibleOperationOutput: + """ + Invokes the QueryIncompatibleOperation operation. + + Args: + input: + An instance of `QueryIncompatibleOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `QueryIncompatibleOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=QUERY_INCOMPATIBLE_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def simple_scalar_properties( + self, input: SimpleScalarPropertiesInput, plugins: list[Plugin] | None = None + ) -> SimpleScalarPropertiesOutput: + """ + Invokes the SimpleScalarProperties operation. + + Args: + input: + An instance of `SimpleScalarPropertiesInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `SimpleScalarPropertiesOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=SIMPLE_SCALAR_PROPERTIES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) diff --git a/codegen-output/aws-json-1-0/src/awsjson10/config.py b/codegen-output/aws-json-1-0/src/awsjson10/config.py new file mode 100644 index 000000000..41b2b5f69 --- /dev/null +++ b/codegen-output/aws-json-1-0/src/awsjson10/config.py @@ -0,0 +1,229 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from dataclasses import dataclass, field +from typing import Any, Callable, ClassVar, Self, TypeAlias, Union, Unpack + +from smithy_aws_core.aio.protocols import AwsJson10ClientProtocol +from smithy_aws_core.auth import SigV4AuthScheme +from smithy_aws_core.config import AwsConfigOverrides, FileSystem +from smithy_aws_core.config.aws_config import AsyncAwsConfig +from smithy_aws_core.config.resolvers import EndpointUriResolver +from smithy_aws_core.config.types import FieldSpec +from smithy_aws_core.endpoints.standard_regional import ( + StandardRegionalEndpointsResolver, +) +from smithy_aws_core.identity import AWSCredentialsIdentity, AWSIdentityProperties +from smithy_core.aio.interfaces import ClientProtocol, EndpointResolver +from smithy_core.aio.interfaces.auth import AuthScheme +from smithy_core.aio.interfaces.identity import IdentityResolver +from smithy_core.interceptors import Interceptor +from smithy_core.shapes import ShapeID +from smithy_http.aio.aiohttp import AIOHTTPClient + +from ._private.schemas import JSON_RPC10 as _SCHEMA_JSON_RPC10 +from .auth import HTTPAuthSchemeResolver +from .models import ( + ContentTypeParametersInput, + ContentTypeParametersOutput, + EmptyInputAndEmptyOutputInput, + EmptyInputAndEmptyOutputOutput, + EndpointOperationInput, + EndpointOperationOutput, + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HostWithPathOperationInput, + HostWithPathOperationOutput, + JsonUnionsInput, + JsonUnionsOutput, + NoInputAndNoOutputInput, + NoInputAndNoOutputOutput, + NoInputAndOutputInput, + NoInputAndOutputOutput, + OperationWithDefaultsInput, + OperationWithDefaultsOutput, + OperationWithNestedStructureInput, + OperationWithNestedStructureOutput, + OperationWithRequiredMembersInput, + OperationWithRequiredMembersOutput, + OperationWithRequiredMembersWithDefaultsInput, + OperationWithRequiredMembersWithDefaultsOutput, + PutWithContentEncodingInput, + PutWithContentEncodingOutput, + QueryIncompatibleOperationInput, + QueryIncompatibleOperationOutput, + SimpleScalarPropertiesInput, + SimpleScalarPropertiesOutput, +) + + +_ServiceInterceptor = Union[ + Interceptor[ContentTypeParametersInput, ContentTypeParametersOutput, Any, Any], + Interceptor[ + EmptyInputAndEmptyOutputInput, EmptyInputAndEmptyOutputOutput, Any, Any + ], + Interceptor[EndpointOperationInput, EndpointOperationOutput, Any, Any], + Interceptor[ + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + Any, + Any, + ], + Interceptor[GreetingWithErrorsInput, GreetingWithErrorsOutput, Any, Any], + Interceptor[HostWithPathOperationInput, HostWithPathOperationOutput, Any, Any], + Interceptor[JsonUnionsInput, JsonUnionsOutput, Any, Any], + Interceptor[NoInputAndNoOutputInput, NoInputAndNoOutputOutput, Any, Any], + Interceptor[NoInputAndOutputInput, NoInputAndOutputOutput, Any, Any], + Interceptor[OperationWithDefaultsInput, OperationWithDefaultsOutput, Any, Any], + Interceptor[ + OperationWithNestedStructureInput, OperationWithNestedStructureOutput, Any, Any + ], + Interceptor[ + OperationWithRequiredMembersInput, OperationWithRequiredMembersOutput, Any, Any + ], + Interceptor[ + OperationWithRequiredMembersWithDefaultsInput, + OperationWithRequiredMembersWithDefaultsOutput, + Any, + Any, + ], + Interceptor[PutWithContentEncodingInput, PutWithContentEncodingOutput, Any, Any], + Interceptor[ + QueryIncompatibleOperationInput, QueryIncompatibleOperationOutput, Any, Any + ], + Interceptor[SimpleScalarPropertiesInput, SimpleScalarPropertiesOutput, Any, Any], +] + + +class _AsyncJSONRPC10ConfigOverrides(AwsConfigOverrides, total=False): + endpoint_resolver: EndpointResolver | None + protocol: ClientProtocol[Any, Any] | None + auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None + auth_scheme_resolver: HTTPAuthSchemeResolver | None + + +@dataclass(kw_only=True, repr=False, init=False) +class AsyncJSONRPC10Config(AsyncAwsConfig): + """JSON RPC 10 configuration (async-resolved).""" + + endpoint_resolver: EndpointResolver | None = None + """ + The endpoint resolver used to resolve the final endpoint per-operation + based on the configuration. + """ + + protocol: ClientProtocol[Any, Any] | None = None + """The protocol to serialize and deserialize requests with.""" + + interceptors: list[_ServiceInterceptor] = field(default_factory=lambda: []) + """ + The list of interceptors, which are hooks that are called during the + execution of a request. + """ + + auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None = None + """A map of auth scheme ids to auth schemes.""" + + auth_scheme_resolver: HTTPAuthSchemeResolver | None = None + """ + An auth scheme resolver that determines the auth scheme for each + operation. + """ + + aws_credentials_identity_resolver: ( + IdentityResolver[AWSCredentialsIdentity, AWSIdentityProperties] | None + ) = None + """Resolves AWS Credentials. Required for operations that use Sigv4 Auth.""" + + region: str | None = None + """ + The AWS region to connect to. The configured region is used to determine + the service endpoint. + """ + + aws_access_key_id: str | None = None + """The identifier for a secret access key.""" + + aws_secret_access_key: str | None = None + """A secret access key that can be used to sign requests.""" + + aws_session_token: str | None = None + """The session token used with temporary AWS credentials.""" + + user_agent_extra: str | None = None + """Additional suffix to be added to the User-Agent header.""" + + sdk_ua_app_id: str | None = None + """ + A unique and opaque application ID that is appended to the User-Agent + header. + """ + + _FIELDS: ClassVar[dict[str, FieldSpec]] = { + "aws_credentials_identity_resolver": FieldSpec(default=None), + "region": FieldSpec(default=None), + "aws_access_key_id": FieldSpec(default=None), + "aws_secret_access_key": FieldSpec(default=None), + "aws_session_token": FieldSpec(default=None), + "user_agent_extra": FieldSpec(default=None), + "sdk_ua_app_id": FieldSpec(default=None), + **AsyncAwsConfig._FIELDS, + "endpoint_uri": FieldSpec( + default=None, resolver=EndpointUriResolver("json_rpc_10") + ), + "endpoint_resolver": FieldSpec( + default_factory=lambda: StandardRegionalEndpointsResolver( + endpoint_prefix="jsonrpc10" + ) + ), + "protocol": FieldSpec( + default_factory=lambda: AwsJson10ClientProtocol(_SCHEMA_JSON_RPC10) + ), + "auth_schemes": FieldSpec( + default_factory=lambda: { + ShapeID("aws.auth#sigv4"): SigV4AuthScheme(service="jsonrpc10") + } + ), + "auth_scheme_resolver": FieldSpec(default_factory=HTTPAuthSchemeResolver), + "transport": FieldSpec(default_factory=lambda: AIOHTTPClient()), + } + + def set_auth_scheme(self, scheme: AuthScheme[Any, Any, Any, Any]) -> None: + """ + Set an auth scheme implementation using its scheme ID. :param scheme: + The auth scheme to add or replace. + """ + auth_schemes = dict(self.auth_schemes or {}) + auth_schemes[scheme.scheme_id] = scheme + self.auth_schemes = auth_schemes + + @classmethod + async def resolve( # pyright: ignore[reportIncompatibleMethodOverride] + cls, + *, + profile: str | None = None, + fs: FileSystem | None = None, + config_file_path: str | None = None, + credentials_file_path: str | None = None, + **overrides: Unpack[_AsyncJSONRPC10ConfigOverrides], + ) -> Self: + """ + Resolve config from environment, config files, defaults, and explicit + overrides. + """ + return await cls._resolve( + profile=profile, + fs=fs, + config_file_path=config_file_path, + credentials_file_path=credentials_file_path, + overrides=overrides, + ) + + +Plugin: TypeAlias = Callable[[AsyncJSONRPC10Config], None] +""" +A callable that customizes a client configuration. Service-level plugins +are applied once to the base configuration inherited by every operation. +Operation-level plugins apply only to a single operation invocation. +""" diff --git a/codegen-output/aws-json-1-0/src/awsjson10/models.py b/codegen-output/aws-json-1-0/src/awsjson10/models.py new file mode 100644 index 000000000..d1c06df81 --- /dev/null +++ b/codegen-output/aws-json-1-0/src/awsjson10/models.py @@ -0,0 +1,3351 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from base64 import b64decode +from dataclasses import dataclass, field +from datetime import datetime, timezone +from enum import IntEnum, StrEnum +import logging +from typing import Any, Literal, Self, Union + +from smithy_core.deserializers import ShapeDeserializer +from smithy_core.documents import Document, TypeRegistry +from smithy_core.exceptions import ModeledError, SerializationError +from smithy_core.schemas import APIOperation, Schema +from smithy_core.serializers import ShapeSerializer +from smithy_core.shapes import ShapeID +from smithy_core.types import UnknownEnumMixin + +from ._private.schemas import ( + CLIENT_OPTIONAL_DEFAULTS as _SCHEMA_CLIENT_OPTIONAL_DEFAULTS, + COMPLEX_ERROR as _SCHEMA_COMPLEX_ERROR, + COMPLEX_NESTED_ERROR_DATA as _SCHEMA_COMPLEX_NESTED_ERROR_DATA, + CONTENT_TYPE_PARAMETERS as _SCHEMA_CONTENT_TYPE_PARAMETERS, + CONTENT_TYPE_PARAMETERS_INPUT as _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, + CONTENT_TYPE_PARAMETERS_OUTPUT as _SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, + DEFAULTS as _SCHEMA_DEFAULTS, + DIALOG as _SCHEMA_DIALOG, + EMPTY_INPUT_AND_EMPTY_OUTPUT as _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT, + EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT as _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, + EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT as _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, + ENDPOINT_OPERATION as _SCHEMA_ENDPOINT_OPERATION, + ENDPOINT_OPERATION_INPUT as _SCHEMA_ENDPOINT_OPERATION_INPUT, + ENDPOINT_OPERATION_OUTPUT as _SCHEMA_ENDPOINT_OPERATION_OUTPUT, + ENDPOINT_WITH_HOST_LABEL_OPERATION as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION, + ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, + ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, + FAREWELL as _SCHEMA_FAREWELL, + FOO_ERROR as _SCHEMA_FOO_ERROR, + GREETING_STRUCT as _SCHEMA_GREETING_STRUCT, + GREETING_WITH_ERRORS as _SCHEMA_GREETING_WITH_ERRORS, + GREETING_WITH_ERRORS_INPUT as _SCHEMA_GREETING_WITH_ERRORS_INPUT, + GREETING_WITH_ERRORS_OUTPUT as _SCHEMA_GREETING_WITH_ERRORS_OUTPUT, + HOST_WITH_PATH_OPERATION as _SCHEMA_HOST_WITH_PATH_OPERATION, + HOST_WITH_PATH_OPERATION_INPUT as _SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, + HOST_WITH_PATH_OPERATION_OUTPUT as _SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, + INVALID_GREETING as _SCHEMA_INVALID_GREETING, + JSON_UNIONS as _SCHEMA_JSON_UNIONS, + JSON_UNIONS_INPUT as _SCHEMA_JSON_UNIONS_INPUT, + JSON_UNIONS_OUTPUT as _SCHEMA_JSON_UNIONS_OUTPUT, + MY_UNION as _SCHEMA_MY_UNION, + NO_INPUT_AND_NO_OUTPUT as _SCHEMA_NO_INPUT_AND_NO_OUTPUT, + NO_INPUT_AND_NO_OUTPUT_INPUT as _SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, + NO_INPUT_AND_NO_OUTPUT_OUTPUT as _SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, + NO_INPUT_AND_OUTPUT as _SCHEMA_NO_INPUT_AND_OUTPUT, + NO_INPUT_AND_OUTPUT_INPUT as _SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, + NO_INPUT_AND_OUTPUT_OUTPUT as _SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, + OPERATION_WITH_DEFAULTS as _SCHEMA_OPERATION_WITH_DEFAULTS, + OPERATION_WITH_DEFAULTS_INPUT as _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT, + OPERATION_WITH_DEFAULTS_OUTPUT as _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT, + OPERATION_WITH_NESTED_STRUCTURE as _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE, + OPERATION_WITH_NESTED_STRUCTURE_INPUT as _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT, + OPERATION_WITH_NESTED_STRUCTURE_OUTPUT as _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT, + OPERATION_WITH_REQUIRED_MEMBERS as _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS, + OPERATION_WITH_REQUIRED_MEMBERS_INPUT as _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_INPUT, + OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT as _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT, + OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS as _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS, + OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_INPUT as _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_INPUT, + OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT as _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT, + PUT_WITH_CONTENT_ENCODING as _SCHEMA_PUT_WITH_CONTENT_ENCODING, + PUT_WITH_CONTENT_ENCODING_INPUT as _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, + PUT_WITH_CONTENT_ENCODING_OUTPUT as _SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, + QUERY_INCOMPATIBLE_OPERATION as _SCHEMA_QUERY_INCOMPATIBLE_OPERATION, + QUERY_INCOMPATIBLE_OPERATION_INPUT as _SCHEMA_QUERY_INCOMPATIBLE_OPERATION_INPUT, + QUERY_INCOMPATIBLE_OPERATION_OUTPUT as _SCHEMA_QUERY_INCOMPATIBLE_OPERATION_OUTPUT, + SIMPLE_SCALAR_PROPERTIES as _SCHEMA_SIMPLE_SCALAR_PROPERTIES, + SIMPLE_SCALAR_PROPERTIES_INPUT as _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, + SIMPLE_SCALAR_PROPERTIES_OUTPUT as _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, + TOP_LEVEL as _SCHEMA_TOP_LEVEL, +) + + +logger = logging.getLogger(__name__) + + +class ServiceError(ModeledError): + """ + Base error for all errors in the service. + + Some exceptions do not extend from this class, including + synthetic, implicit, and shared exception types. + """ + + +@dataclass(kw_only=True) +class ClientOptionalDefaults: + """Dataclass for ClientOptionalDefaults structure.""" + + member: int = 0 + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CLIENT_OPTIONAL_DEFAULTS, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.member is not None: + serializer.write_integer( + _SCHEMA_CLIENT_OPTIONAL_DEFAULTS.members["member"], self.member + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["member"] = de.read_integer( + _SCHEMA_CLIENT_OPTIONAL_DEFAULTS.members["member"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_CLIENT_OPTIONAL_DEFAULTS, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ComplexNestedErrorData: + """Dataclass for ComplexNestedErrorData structure.""" + + foo: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_COMPLEX_NESTED_ERROR_DATA, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_COMPLEX_NESTED_ERROR_DATA.members["Foo"], self.foo + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_COMPLEX_NESTED_ERROR_DATA.members["Foo"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_COMPLEX_NESTED_ERROR_DATA, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ComplexError(ServiceError): + """This error is thrown when a request is invalid.""" + + fault: Literal["client", "server"] | None = "client" + + top_level: str | None = None + + nested: ComplexNestedErrorData | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_COMPLEX_ERROR, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.top_level is not None: + serializer.write_string( + _SCHEMA_COMPLEX_ERROR.members["TopLevel"], self.top_level + ) + + if self.nested is not None: + serializer.write_struct( + _SCHEMA_COMPLEX_ERROR.members["Nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["top_level"] = de.read_string( + _SCHEMA_COMPLEX_ERROR.members["TopLevel"] + ) + + case 1: + kwargs["nested"] = ComplexNestedErrorData.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_COMPLEX_ERROR, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ContentTypeParametersInput: + """Dataclass for ContentTypeParametersInput structure.""" + + value: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.value is not None: + serializer.write_integer( + _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT.members["value"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = de.read_integer( + _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT.members["value"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class ContentTypeParametersOutput: + """Dataclass for ContentTypeParametersOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, consumer=_consumer + ) + return kwargs + + +CONTENT_TYPE_PARAMETERS = APIOperation( + input=ContentTypeParametersInput, + output=ContentTypeParametersOutput, + schema=_SCHEMA_CONTENT_TYPE_PARAMETERS, + input_schema=_SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, + output_schema=_SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +class TestEnum(UnknownEnumMixin, StrEnum): + FOO = "FOO" + BAR = "BAR" + BAZ = "BAZ" + + +class TestIntEnum(UnknownEnumMixin, IntEnum): + ONE = 1 + TWO = 2 + + +def _serialize_test_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_test_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_test_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_test_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class Defaults: + """Dataclass for Defaults structure.""" + + default_string: str = "hi" + + default_boolean: bool = True + + default_list: list[str] = field(default_factory=list[str]) + + default_document_map: Document = field(default_factory=lambda: Document(dict())) + + default_document_string: Document = field(default_factory=lambda: Document("hi")) + + default_document_boolean: Document = field(default_factory=lambda: Document(True)) + + default_document_list: Document = field(default_factory=lambda: Document(list())) + + default_null_document: Document = field(default_factory=lambda: Document(None)) + + default_timestamp: datetime = datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc) + + default_blob: bytes = b64decode("YWJj") + + default_byte: int = 1 + + default_short: int = 1 + + default_integer: int = 10 + + default_long: int = 100 + + default_float: float = 1.0 + + default_double: float = 1.0 + + default_map: dict[str, str] = field(default_factory=dict[str, str]) + + default_enum: str = TestEnum("FOO") + + default_int_enum: int = TestIntEnum(1) + + empty_string: str = "" + + false_boolean: bool = False + + empty_blob: bytes = b64decode("") + + zero_byte: int = 0 + + zero_short: int = 0 + + zero_integer: int = 0 + + zero_long: int = 0 + + zero_float: float = 0.0 + + zero_double: float = 0.0 + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DEFAULTS, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string( + _SCHEMA_DEFAULTS.members["defaultString"], self.default_string + ) + serializer.write_boolean( + _SCHEMA_DEFAULTS.members["defaultBoolean"], self.default_boolean + ) + _serialize_test_string_list( + serializer, _SCHEMA_DEFAULTS.members["defaultList"], self.default_list + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultDocumentMap"], self.default_document_map + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultDocumentString"], + self.default_document_string, + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultDocumentBoolean"], + self.default_document_boolean, + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultDocumentList"], self.default_document_list + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultNullDocument"], self.default_null_document + ) + serializer.write_timestamp( + _SCHEMA_DEFAULTS.members["defaultTimestamp"], self.default_timestamp + ) + serializer.write_blob( + _SCHEMA_DEFAULTS.members["defaultBlob"], self.default_blob + ) + serializer.write_byte( + _SCHEMA_DEFAULTS.members["defaultByte"], self.default_byte + ) + serializer.write_short( + _SCHEMA_DEFAULTS.members["defaultShort"], self.default_short + ) + serializer.write_integer( + _SCHEMA_DEFAULTS.members["defaultInteger"], self.default_integer + ) + serializer.write_long( + _SCHEMA_DEFAULTS.members["defaultLong"], self.default_long + ) + serializer.write_float( + _SCHEMA_DEFAULTS.members["defaultFloat"], self.default_float + ) + serializer.write_double( + _SCHEMA_DEFAULTS.members["defaultDouble"], self.default_double + ) + _serialize_test_string_map( + serializer, _SCHEMA_DEFAULTS.members["defaultMap"], self.default_map + ) + serializer.write_string( + _SCHEMA_DEFAULTS.members["defaultEnum"], self.default_enum + ) + serializer.write_integer( + _SCHEMA_DEFAULTS.members["defaultIntEnum"], self.default_int_enum + ) + serializer.write_string( + _SCHEMA_DEFAULTS.members["emptyString"], self.empty_string + ) + serializer.write_boolean( + _SCHEMA_DEFAULTS.members["falseBoolean"], self.false_boolean + ) + serializer.write_blob(_SCHEMA_DEFAULTS.members["emptyBlob"], self.empty_blob) + serializer.write_byte(_SCHEMA_DEFAULTS.members["zeroByte"], self.zero_byte) + serializer.write_short(_SCHEMA_DEFAULTS.members["zeroShort"], self.zero_short) + serializer.write_integer( + _SCHEMA_DEFAULTS.members["zeroInteger"], self.zero_integer + ) + serializer.write_long(_SCHEMA_DEFAULTS.members["zeroLong"], self.zero_long) + serializer.write_float(_SCHEMA_DEFAULTS.members["zeroFloat"], self.zero_float) + serializer.write_double( + _SCHEMA_DEFAULTS.members["zeroDouble"], self.zero_double + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["default_string"] = de.read_string( + _SCHEMA_DEFAULTS.members["defaultString"] + ) + + case 1: + kwargs["default_boolean"] = de.read_boolean( + _SCHEMA_DEFAULTS.members["defaultBoolean"] + ) + + case 2: + kwargs["default_list"] = _deserialize_test_string_list( + de, _SCHEMA_DEFAULTS.members["defaultList"] + ) + + case 3: + kwargs["default_document_map"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultDocumentMap"] + ) + + case 4: + kwargs["default_document_string"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultDocumentString"] + ) + + case 5: + kwargs["default_document_boolean"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultDocumentBoolean"] + ) + + case 6: + kwargs["default_document_list"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultDocumentList"] + ) + + case 7: + kwargs["default_null_document"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultNullDocument"] + ) + + case 8: + kwargs["default_timestamp"] = de.read_timestamp( + _SCHEMA_DEFAULTS.members["defaultTimestamp"] + ) + + case 9: + kwargs["default_blob"] = de.read_blob( + _SCHEMA_DEFAULTS.members["defaultBlob"] + ) + + case 10: + kwargs["default_byte"] = de.read_byte( + _SCHEMA_DEFAULTS.members["defaultByte"] + ) + + case 11: + kwargs["default_short"] = de.read_short( + _SCHEMA_DEFAULTS.members["defaultShort"] + ) + + case 12: + kwargs["default_integer"] = de.read_integer( + _SCHEMA_DEFAULTS.members["defaultInteger"] + ) + + case 13: + kwargs["default_long"] = de.read_long( + _SCHEMA_DEFAULTS.members["defaultLong"] + ) + + case 14: + kwargs["default_float"] = de.read_float( + _SCHEMA_DEFAULTS.members["defaultFloat"] + ) + + case 15: + kwargs["default_double"] = de.read_double( + _SCHEMA_DEFAULTS.members["defaultDouble"] + ) + + case 16: + kwargs["default_map"] = _deserialize_test_string_map( + de, _SCHEMA_DEFAULTS.members["defaultMap"] + ) + + case 17: + kwargs["default_enum"] = TestEnum( + de.read_string(_SCHEMA_DEFAULTS.members["defaultEnum"]) + ) + + case 18: + kwargs["default_int_enum"] = TestIntEnum( + de.read_integer(_SCHEMA_DEFAULTS.members["defaultIntEnum"]) + ) + + case 19: + kwargs["empty_string"] = de.read_string( + _SCHEMA_DEFAULTS.members["emptyString"] + ) + + case 20: + kwargs["false_boolean"] = de.read_boolean( + _SCHEMA_DEFAULTS.members["falseBoolean"] + ) + + case 21: + kwargs["empty_blob"] = de.read_blob( + _SCHEMA_DEFAULTS.members["emptyBlob"] + ) + + case 22: + kwargs["zero_byte"] = de.read_byte( + _SCHEMA_DEFAULTS.members["zeroByte"] + ) + + case 23: + kwargs["zero_short"] = de.read_short( + _SCHEMA_DEFAULTS.members["zeroShort"] + ) + + case 24: + kwargs["zero_integer"] = de.read_integer( + _SCHEMA_DEFAULTS.members["zeroInteger"] + ) + + case 25: + kwargs["zero_long"] = de.read_long( + _SCHEMA_DEFAULTS.members["zeroLong"] + ) + + case 26: + kwargs["zero_float"] = de.read_float( + _SCHEMA_DEFAULTS.members["zeroFloat"] + ) + + case 27: + kwargs["zero_double"] = de.read_double( + _SCHEMA_DEFAULTS.members["zeroDouble"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DEFAULTS, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class Farewell: + """Dataclass for Farewell structure.""" + + phrase: str = "bye" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FAREWELL, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_FAREWELL.members["phrase"], self.phrase) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["phrase"] = de.read_string( + _SCHEMA_FAREWELL.members["phrase"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FAREWELL, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class Dialog: + """Dataclass for Dialog structure.""" + + language: str | None = None + + greeting: str = "hi" + + farewell: Farewell | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DIALOG, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.language is not None: + serializer.write_string(_SCHEMA_DIALOG.members["language"], self.language) + + serializer.write_string(_SCHEMA_DIALOG.members["greeting"], self.greeting) + if self.farewell is not None: + serializer.write_struct(_SCHEMA_DIALOG.members["farewell"], self.farewell) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["language"] = de.read_string( + _SCHEMA_DIALOG.members["language"] + ) + + case 1: + kwargs["greeting"] = de.read_string( + _SCHEMA_DIALOG.members["greeting"] + ) + + case 2: + kwargs["farewell"] = Farewell.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DIALOG, consumer=_consumer) + return kwargs + + @classmethod + def _smithy_default(cls) -> Self: + return cls() + + +def _serialize_dialog_list( + serializer: ShapeSerializer, schema: Schema, value: list[Dialog] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_struct(member_schema, e) + + +def _deserialize_dialog_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[Dialog]: + result: list[Dialog] = [] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(Dialog.deserialize(d)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_dialog_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, Dialog] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_struct(value_schema, v)) + + +def _deserialize_dialog_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, Dialog]: + result: dict[str, Dialog] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = Dialog.deserialize(d) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class EmptyInputAndEmptyOutputInput: + """Dataclass for EmptyInputAndEmptyOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class EmptyInputAndEmptyOutputOutput: + """Dataclass for EmptyInputAndEmptyOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, consumer=_consumer + ) + return kwargs + + +EMPTY_INPUT_AND_EMPTY_OUTPUT = APIOperation( + input=EmptyInputAndEmptyOutputInput, + output=EmptyInputAndEmptyOutputOutput, + schema=_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT, + input_schema=_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, + output_schema=_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EndpointOperationInput: + """Dataclass for EndpointOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ENDPOINT_OPERATION_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class EndpointOperationOutput: + """Dataclass for EndpointOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ENDPOINT_OPERATION_OUTPUT, consumer=_consumer) + return kwargs + + +ENDPOINT_OPERATION = APIOperation( + input=EndpointOperationInput, + output=EndpointOperationOutput, + schema=_SCHEMA_ENDPOINT_OPERATION, + input_schema=_SCHEMA_ENDPOINT_OPERATION_INPUT, + output_schema=_SCHEMA_ENDPOINT_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EndpointWithHostLabelOperationInput: + """Dataclass for EndpointWithHostLabelOperationInput structure.""" + + label: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.label is not None: + serializer.write_string( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT.members["label"], + self.label, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["label"] = de.read_string( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT.members[ + "label" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class EndpointWithHostLabelOperationOutput: + """Dataclass for EndpointWithHostLabelOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +ENDPOINT_WITH_HOST_LABEL_OPERATION = APIOperation( + input=EndpointWithHostLabelOperationInput, + output=EndpointWithHostLabelOperationOutput, + schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION, + input_schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, + output_schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class FooError(ServiceError): + """ + This error has test cases that test some of the dark corners of Amazon + service framework history. It should only be implemented by clients. + """ + + fault: Literal["client", "server"] | None = "server" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FOO_ERROR, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FOO_ERROR, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class GreetingWithErrorsInput: + """Dataclass for GreetingWithErrorsInput structure.""" + + greeting: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_WITH_ERRORS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.greeting is not None: + serializer.write_string( + _SCHEMA_GREETING_WITH_ERRORS_INPUT.members["greeting"], self.greeting + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["greeting"] = de.read_string( + _SCHEMA_GREETING_WITH_ERRORS_INPUT.members["greeting"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_GREETING_WITH_ERRORS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class GreetingWithErrorsOutput: + """Dataclass for GreetingWithErrorsOutput structure.""" + + greeting: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_WITH_ERRORS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.greeting is not None: + serializer.write_string( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT.members["greeting"], self.greeting + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["greeting"] = de.read_string( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT.members["greeting"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class InvalidGreeting(ServiceError): + """This error is thrown when an invalid greeting value is provided.""" + + fault: Literal["client", "server"] | None = "client" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INVALID_GREETING, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.message is not None: + serializer.write_string( + _SCHEMA_INVALID_GREETING.members["Message"], self.message + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["message"] = de.read_string( + _SCHEMA_INVALID_GREETING.members["Message"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_INVALID_GREETING, consumer=_consumer) + return kwargs + + +GREETING_WITH_ERRORS = APIOperation( + input=GreetingWithErrorsInput, + output=GreetingWithErrorsOutput, + schema=_SCHEMA_GREETING_WITH_ERRORS, + input_schema=_SCHEMA_GREETING_WITH_ERRORS_INPUT, + output_schema=_SCHEMA_GREETING_WITH_ERRORS_OUTPUT, + error_registry=TypeRegistry( + { + ShapeID("aws.protocoltests.json10#InvalidGreeting"): InvalidGreeting, + ShapeID("aws.protocoltests.json10#ComplexError"): ComplexError, + ShapeID("aws.protocoltests.json10#FooError"): FooError, + } + ), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[_SCHEMA_INVALID_GREETING, _SCHEMA_COMPLEX_ERROR, _SCHEMA_FOO_ERROR], +) + + +@dataclass(kw_only=True) +class HostWithPathOperationInput: + """Dataclass for HostWithPathOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HostWithPathOperationOutput: + """Dataclass for HostWithPathOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +HOST_WITH_PATH_OPERATION = APIOperation( + input=HostWithPathOperationInput, + output=HostWithPathOperationOutput, + schema=_SCHEMA_HOST_WITH_PATH_OPERATION, + input_schema=_SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, + output_schema=_SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +class FooEnum(UnknownEnumMixin, StrEnum): + FOO = "Foo" + BAZ = "Baz" + BAR = "Bar" + ONE = "1" + ZERO = "0" + + +class IntegerEnum(UnknownEnumMixin, IntEnum): + A = 1 + B = 2 + C = 3 + + +def _serialize_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class GreetingStruct: + """Dataclass for GreetingStruct structure.""" + + hi: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_STRUCT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.hi is not None: + serializer.write_string(_SCHEMA_GREETING_STRUCT.members["hi"], self.hi) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["hi"] = de.read_string(_SCHEMA_GREETING_STRUCT.members["hi"]) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_GREETING_STRUCT, consumer=_consumer) + return kwargs + + +@dataclass +class MyUnionStringValue: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_MY_UNION.members["stringValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_MY_UNION.members["stringValue"]) + ) + + +@dataclass +class MyUnionBooleanValue: + value: bool + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_boolean(_SCHEMA_MY_UNION.members["booleanValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_boolean(_SCHEMA_MY_UNION.members["booleanValue"]) + ) + + +@dataclass +class MyUnionNumberValue: + value: int + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_integer(_SCHEMA_MY_UNION.members["numberValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_integer(_SCHEMA_MY_UNION.members["numberValue"]) + ) + + +@dataclass +class MyUnionBlobValue: + value: bytes + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_blob(_SCHEMA_MY_UNION.members["blobValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=deserializer.read_blob(_SCHEMA_MY_UNION.members["blobValue"])) + + +@dataclass +class MyUnionTimestampValue: + value: datetime + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_timestamp( + _SCHEMA_MY_UNION.members["timestampValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_timestamp( + _SCHEMA_MY_UNION.members["timestampValue"] + ) + ) + + +@dataclass +class MyUnionEnumValue: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_MY_UNION.members["enumValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=FooEnum( + deserializer.read_string(_SCHEMA_MY_UNION.members["enumValue"]) + ) + ) + + +@dataclass +class MyUnionIntEnumValue: + value: int + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_integer(_SCHEMA_MY_UNION.members["intEnumValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=IntegerEnum( + deserializer.read_integer(_SCHEMA_MY_UNION.members["intEnumValue"]) + ) + ) + + +@dataclass +class MyUnionListValue: + value: list[str] + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + _serialize_string_list( + serializer, _SCHEMA_MY_UNION.members["listValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=_deserialize_string_list( + deserializer, _SCHEMA_MY_UNION.members["listValue"] + ) + ) + + +@dataclass +class MyUnionMapValue: + value: dict[str, str] + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + _serialize_string_map( + serializer, _SCHEMA_MY_UNION.members["mapValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=_deserialize_string_map( + deserializer, _SCHEMA_MY_UNION.members["mapValue"] + ) + ) + + +@dataclass +class MyUnionStructureValue: + value: GreetingStruct + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION.members["structureValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=GreetingStruct.deserialize(deserializer)) + + +@dataclass +class MyUnionUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +MyUnion = Union[ + MyUnionStringValue + | MyUnionBooleanValue + | MyUnionNumberValue + | MyUnionBlobValue + | MyUnionTimestampValue + | MyUnionEnumValue + | MyUnionIntEnumValue + | MyUnionListValue + | MyUnionMapValue + | MyUnionStructureValue + | MyUnionUnknown +] +"""A union with a representative set of types for members.""" + + +class _MyUnionDeserializer: + _result: MyUnion | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> MyUnion: + self._result = None + deserializer.read_struct(_SCHEMA_MY_UNION, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(MyUnionStringValue.deserialize(de)) + + case 1: + self._set_result(MyUnionBooleanValue.deserialize(de)) + + case 2: + self._set_result(MyUnionNumberValue.deserialize(de)) + + case 3: + self._set_result(MyUnionBlobValue.deserialize(de)) + + case 4: + self._set_result(MyUnionTimestampValue.deserialize(de)) + + case 5: + self._set_result(MyUnionEnumValue.deserialize(de)) + + case 6: + self._set_result(MyUnionIntEnumValue.deserialize(de)) + + case 7: + self._set_result(MyUnionListValue.deserialize(de)) + + case 8: + self._set_result(MyUnionMapValue.deserialize(de)) + + case 9: + self._set_result(MyUnionStructureValue.deserialize(de)) + + case _: + self._set_result(MyUnionUnknown(tag=schema.expect_member_name())) + + def _set_result(self, value: MyUnion) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class JsonUnionsInput: + """Dataclass for JsonUnionsInput structure.""" + + contents: MyUnion | None = None + """A union with a representative set of types for members.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_UNIONS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.contents is not None: + serializer.write_struct( + _SCHEMA_JSON_UNIONS_INPUT.members["contents"], self.contents + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["contents"] = _MyUnionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_UNIONS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonUnionsOutput: + """Dataclass for JsonUnionsOutput structure.""" + + contents: MyUnion | None = None + """A union with a representative set of types for members.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_UNIONS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.contents is not None: + serializer.write_struct( + _SCHEMA_JSON_UNIONS_OUTPUT.members["contents"], self.contents + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["contents"] = _MyUnionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_UNIONS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_UNIONS = APIOperation( + input=JsonUnionsInput, + output=JsonUnionsOutput, + schema=_SCHEMA_JSON_UNIONS, + input_schema=_SCHEMA_JSON_UNIONS_INPUT, + output_schema=_SCHEMA_JSON_UNIONS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NoInputAndNoOutputInput: + """Dataclass for NoInputAndNoOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class NoInputAndNoOutputOutput: + """Dataclass for NoInputAndNoOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, consumer=_consumer + ) + return kwargs + + +NO_INPUT_AND_NO_OUTPUT = APIOperation( + input=NoInputAndNoOutputInput, + output=NoInputAndNoOutputOutput, + schema=_SCHEMA_NO_INPUT_AND_NO_OUTPUT, + input_schema=_SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, + output_schema=_SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NoInputAndOutputInput: + """Dataclass for NoInputAndOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class NoInputAndOutputOutput: + """Dataclass for NoInputAndOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, consumer=_consumer) + return kwargs + + +NO_INPUT_AND_OUTPUT = APIOperation( + input=NoInputAndOutputInput, + output=NoInputAndOutputOutput, + schema=_SCHEMA_NO_INPUT_AND_OUTPUT, + input_schema=_SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, + output_schema=_SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class OperationWithDefaultsInput: + """Dataclass for OperationWithDefaultsInput structure.""" + + defaults: Defaults | None = None + + client_optional_defaults: ClientOptionalDefaults | None = None + + top_level_default: str = "hi" + + other_top_level_default: int = 0 + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_DEFAULTS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.defaults is not None: + serializer.write_struct( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["defaults"], self.defaults + ) + + if self.client_optional_defaults is not None: + serializer.write_struct( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["clientOptionalDefaults"], + self.client_optional_defaults, + ) + + if self.top_level_default is not None: + serializer.write_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["topLevelDefault"], + self.top_level_default, + ) + + if self.other_top_level_default is not None: + serializer.write_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["otherTopLevelDefault"], + self.other_top_level_default, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["defaults"] = Defaults.deserialize(de) + + case 1: + kwargs["client_optional_defaults"] = ( + ClientOptionalDefaults.deserialize(de) + ) + + case 2: + kwargs["top_level_default"] = de.read_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["topLevelDefault"] + ) + + case 3: + kwargs["other_top_level_default"] = de.read_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members[ + "otherTopLevelDefault" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class OperationWithDefaultsOutput: + """Dataclass for OperationWithDefaultsOutput structure.""" + + default_string: str = "hi" + + default_boolean: bool = True + + default_list: list[str] = field(default_factory=list[str]) + + default_document_map: Document = field(default_factory=lambda: Document(dict())) + + default_document_string: Document = field(default_factory=lambda: Document("hi")) + + default_document_boolean: Document = field(default_factory=lambda: Document(True)) + + default_document_list: Document = field(default_factory=lambda: Document(list())) + + default_null_document: Document = field(default_factory=lambda: Document(None)) + + default_timestamp: datetime = datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc) + + default_blob: bytes = b64decode("YWJj") + + default_byte: int = 1 + + default_short: int = 1 + + default_integer: int = 10 + + default_long: int = 100 + + default_float: float = 1.0 + + default_double: float = 1.0 + + default_map: dict[str, str] = field(default_factory=dict[str, str]) + + default_enum: str = TestEnum("FOO") + + default_int_enum: int = TestIntEnum(1) + + empty_string: str = "" + + false_boolean: bool = False + + empty_blob: bytes = b64decode("") + + zero_byte: int = 0 + + zero_short: int = 0 + + zero_integer: int = 0 + + zero_long: int = 0 + + zero_float: float = 0.0 + + zero_double: float = 0.0 + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultString"], + self.default_string, + ) + serializer.write_boolean( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultBoolean"], + self.default_boolean, + ) + _serialize_test_string_list( + serializer, + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultList"], + self.default_list, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDocumentMap"], + self.default_document_map, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDocumentString"], + self.default_document_string, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDocumentBoolean"], + self.default_document_boolean, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDocumentList"], + self.default_document_list, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultNullDocument"], + self.default_null_document, + ) + serializer.write_timestamp( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultTimestamp"], + self.default_timestamp, + ) + serializer.write_blob( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultBlob"], + self.default_blob, + ) + serializer.write_byte( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultByte"], + self.default_byte, + ) + serializer.write_short( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultShort"], + self.default_short, + ) + serializer.write_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultInteger"], + self.default_integer, + ) + serializer.write_long( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultLong"], + self.default_long, + ) + serializer.write_float( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultFloat"], + self.default_float, + ) + serializer.write_double( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDouble"], + self.default_double, + ) + _serialize_test_string_map( + serializer, + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultMap"], + self.default_map, + ) + serializer.write_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultEnum"], + self.default_enum, + ) + serializer.write_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultIntEnum"], + self.default_int_enum, + ) + serializer.write_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["emptyString"], + self.empty_string, + ) + serializer.write_boolean( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["falseBoolean"], + self.false_boolean, + ) + serializer.write_blob( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["emptyBlob"], self.empty_blob + ) + serializer.write_byte( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroByte"], self.zero_byte + ) + serializer.write_short( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroShort"], self.zero_short + ) + serializer.write_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroInteger"], + self.zero_integer, + ) + serializer.write_long( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroLong"], self.zero_long + ) + serializer.write_float( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroFloat"], self.zero_float + ) + serializer.write_double( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroDouble"], + self.zero_double, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["default_string"] = de.read_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultString"] + ) + + case 1: + kwargs["default_boolean"] = de.read_boolean( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultBoolean"] + ) + + case 2: + kwargs["default_list"] = _deserialize_test_string_list( + de, + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultList"], + ) + + case 3: + kwargs["default_document_map"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultDocumentMap" + ] + ) + + case 4: + kwargs["default_document_string"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultDocumentString" + ] + ) + + case 5: + kwargs["default_document_boolean"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultDocumentBoolean" + ] + ) + + case 6: + kwargs["default_document_list"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultDocumentList" + ] + ) + + case 7: + kwargs["default_null_document"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultNullDocument" + ] + ) + + case 8: + kwargs["default_timestamp"] = de.read_timestamp( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultTimestamp" + ] + ) + + case 9: + kwargs["default_blob"] = de.read_blob( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultBlob"] + ) + + case 10: + kwargs["default_byte"] = de.read_byte( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultByte"] + ) + + case 11: + kwargs["default_short"] = de.read_short( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultShort"] + ) + + case 12: + kwargs["default_integer"] = de.read_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultInteger"] + ) + + case 13: + kwargs["default_long"] = de.read_long( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultLong"] + ) + + case 14: + kwargs["default_float"] = de.read_float( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultFloat"] + ) + + case 15: + kwargs["default_double"] = de.read_double( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDouble"] + ) + + case 16: + kwargs["default_map"] = _deserialize_test_string_map( + de, _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultMap"] + ) + + case 17: + kwargs["default_enum"] = TestEnum( + de.read_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultEnum" + ] + ) + ) + + case 18: + kwargs["default_int_enum"] = TestIntEnum( + de.read_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultIntEnum" + ] + ) + ) + + case 19: + kwargs["empty_string"] = de.read_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["emptyString"] + ) + + case 20: + kwargs["false_boolean"] = de.read_boolean( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["falseBoolean"] + ) + + case 21: + kwargs["empty_blob"] = de.read_blob( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["emptyBlob"] + ) + + case 22: + kwargs["zero_byte"] = de.read_byte( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroByte"] + ) + + case 23: + kwargs["zero_short"] = de.read_short( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroShort"] + ) + + case 24: + kwargs["zero_integer"] = de.read_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroInteger"] + ) + + case 25: + kwargs["zero_long"] = de.read_long( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroLong"] + ) + + case 26: + kwargs["zero_float"] = de.read_float( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroFloat"] + ) + + case 27: + kwargs["zero_double"] = de.read_double( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroDouble"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT, consumer=_consumer + ) + return kwargs + + +OPERATION_WITH_DEFAULTS = APIOperation( + input=OperationWithDefaultsInput, + output=OperationWithDefaultsOutput, + schema=_SCHEMA_OPERATION_WITH_DEFAULTS, + input_schema=_SCHEMA_OPERATION_WITH_DEFAULTS_INPUT, + output_schema=_SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TopLevel: + """Dataclass for TopLevel structure.""" + + dialog: Dialog + + dialog_list: list[Dialog] = field(default_factory=list[Dialog]) + + dialog_map: dict[str, Dialog] = field(default_factory=dict[str, Dialog]) + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TOP_LEVEL, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TOP_LEVEL.members["dialog"], self.dialog) + _serialize_dialog_list( + serializer, _SCHEMA_TOP_LEVEL.members["dialogList"], self.dialog_list + ) + _serialize_dialog_map( + serializer, _SCHEMA_TOP_LEVEL.members["dialogMap"], self.dialog_map + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["dialog"] = Dialog.deserialize(de) + + case 1: + kwargs["dialog_list"] = _deserialize_dialog_list( + de, _SCHEMA_TOP_LEVEL.members["dialogList"] + ) + + case 2: + kwargs["dialog_map"] = _deserialize_dialog_map( + de, _SCHEMA_TOP_LEVEL.members["dialogMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TOP_LEVEL, consumer=_consumer) + if "dialog" not in kwargs: + kwargs["dialog"] = Dialog._smithy_default() + return kwargs + + +@dataclass(kw_only=True) +class OperationWithNestedStructureInput: + """Dataclass for OperationWithNestedStructureInput structure.""" + + top_level: TopLevel | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.top_level is not None: + serializer.write_struct( + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT.members["topLevel"], + self.top_level, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["top_level"] = TopLevel.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class OperationWithNestedStructureOutput: + """Dataclass for OperationWithNestedStructureOutput structure.""" + + dialog: Dialog + + dialog_list: list[Dialog] = field(default_factory=list[Dialog]) + + dialog_map: dict[str, Dialog] = field(default_factory=dict[str, Dialog]) + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members["dialog"], + self.dialog, + ) + _serialize_dialog_list( + serializer, + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members["dialogList"], + self.dialog_list, + ) + _serialize_dialog_map( + serializer, + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members["dialogMap"], + self.dialog_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["dialog"] = Dialog.deserialize(de) + + case 1: + kwargs["dialog_list"] = _deserialize_dialog_list( + de, + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members[ + "dialogList" + ], + ) + + case 2: + kwargs["dialog_map"] = _deserialize_dialog_map( + de, + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members[ + "dialogMap" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT, consumer=_consumer + ) + if "dialog" not in kwargs: + kwargs["dialog"] = Dialog._smithy_default() + return kwargs + + +OPERATION_WITH_NESTED_STRUCTURE = APIOperation( + input=OperationWithNestedStructureInput, + output=OperationWithNestedStructureOutput, + schema=_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE, + input_schema=_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT, + output_schema=_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class OperationWithRequiredMembersInput: + """Dataclass for OperationWithRequiredMembersInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_INPUT, consumer=_consumer + ) + return kwargs + + +def _serialize_required_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_required_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_required_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_required_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class OperationWithRequiredMembersOutput: + """Dataclass for OperationWithRequiredMembersOutput structure.""" + + required_string: str + + required_boolean: bool + + required_list: list[str] + + required_timestamp: datetime + + required_blob: bytes + + required_byte: int + + required_short: int + + required_integer: int + + required_long: int + + required_float: float + + required_double: float + + required_map: dict[str, str] + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredString"], + self.required_string, + ) + serializer.write_boolean( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredBoolean"], + self.required_boolean, + ) + _serialize_required_string_list( + serializer, + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredList"], + self.required_list, + ) + serializer.write_timestamp( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredTimestamp"], + self.required_timestamp, + ) + serializer.write_blob( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredBlob"], + self.required_blob, + ) + serializer.write_byte( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredByte"], + self.required_byte, + ) + serializer.write_short( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredShort"], + self.required_short, + ) + serializer.write_integer( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredInteger"], + self.required_integer, + ) + serializer.write_long( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredLong"], + self.required_long, + ) + serializer.write_float( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredFloat"], + self.required_float, + ) + serializer.write_double( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredDouble"], + self.required_double, + ) + _serialize_required_string_map( + serializer, + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members["requiredMap"], + self.required_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["required_string"] = de.read_string( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredString" + ] + ) + + case 1: + kwargs["required_boolean"] = de.read_boolean( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredBoolean" + ] + ) + + case 2: + kwargs["required_list"] = _deserialize_required_string_list( + de, + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredList" + ], + ) + + case 3: + kwargs["required_timestamp"] = de.read_timestamp( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredTimestamp" + ] + ) + + case 4: + kwargs["required_blob"] = de.read_blob( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredBlob" + ] + ) + + case 5: + kwargs["required_byte"] = de.read_byte( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredByte" + ] + ) + + case 6: + kwargs["required_short"] = de.read_short( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredShort" + ] + ) + + case 7: + kwargs["required_integer"] = de.read_integer( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredInteger" + ] + ) + + case 8: + kwargs["required_long"] = de.read_long( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredLong" + ] + ) + + case 9: + kwargs["required_float"] = de.read_float( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredFloat" + ] + ) + + case 10: + kwargs["required_double"] = de.read_double( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredDouble" + ] + ) + + case 11: + kwargs["required_map"] = _deserialize_required_string_map( + de, + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT.members[ + "requiredMap" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT, consumer=_consumer + ) + if "required_string" not in kwargs: + kwargs["required_string"] = "" + if "required_boolean" not in kwargs: + kwargs["required_boolean"] = False + if "required_list" not in kwargs: + kwargs["required_list"] = [] + if "required_timestamp" not in kwargs: + kwargs["required_timestamp"] = datetime.fromtimestamp(0, tz=timezone.utc) + if "required_blob" not in kwargs: + kwargs["required_blob"] = b"" + if "required_byte" not in kwargs: + kwargs["required_byte"] = 0 + if "required_short" not in kwargs: + kwargs["required_short"] = 0 + if "required_integer" not in kwargs: + kwargs["required_integer"] = 0 + if "required_long" not in kwargs: + kwargs["required_long"] = 0 + if "required_float" not in kwargs: + kwargs["required_float"] = 0.0 + if "required_double" not in kwargs: + kwargs["required_double"] = 0.0 + if "required_map" not in kwargs: + kwargs["required_map"] = {} + return kwargs + + +OPERATION_WITH_REQUIRED_MEMBERS = APIOperation( + input=OperationWithRequiredMembersInput, + output=OperationWithRequiredMembersOutput, + schema=_SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS, + input_schema=_SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_INPUT, + output_schema=_SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class OperationWithRequiredMembersWithDefaultsInput: + """Dataclass for OperationWithRequiredMembersWithDefaultsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_INPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_INPUT, + consumer=_consumer, + ) + return kwargs + + +class RequiredEnum(UnknownEnumMixin, StrEnum): + FOO = "FOO" + BAR = "BAR" + BAZ = "BAZ" + + +class RequiredIntEnum(UnknownEnumMixin, IntEnum): + ONE = 1 + TWO = 2 + + +@dataclass(kw_only=True) +class OperationWithRequiredMembersWithDefaultsOutput: + """Dataclass for OperationWithRequiredMembersWithDefaultsOutput structure.""" + + required_string: str = "hi" + + required_boolean: bool = True + + required_list: list[str] = field(default_factory=list[str]) + + required_timestamp: datetime = datetime(1970, 1, 1, 0, 0, 1, 0, timezone.utc) + + required_blob: bytes = b64decode("YmxvYg==") + + required_byte: int = 1 + + required_short: int = 1 + + required_integer: int = 10 + + required_long: int = 100 + + required_float: float = 1.0 + + required_double: float = 1.0 + + required_map: dict[str, str] = field(default_factory=dict[str, str]) + + required_enum: str = RequiredEnum("FOO") + + required_int_enum: int = RequiredIntEnum(1) + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredString" + ], + self.required_string, + ) + serializer.write_boolean( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredBoolean" + ], + self.required_boolean, + ) + _serialize_required_string_list( + serializer, + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredList" + ], + self.required_list, + ) + serializer.write_timestamp( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredTimestamp" + ], + self.required_timestamp, + ) + serializer.write_blob( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredBlob" + ], + self.required_blob, + ) + serializer.write_byte( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredByte" + ], + self.required_byte, + ) + serializer.write_short( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredShort" + ], + self.required_short, + ) + serializer.write_integer( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredInteger" + ], + self.required_integer, + ) + serializer.write_long( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredLong" + ], + self.required_long, + ) + serializer.write_float( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredFloat" + ], + self.required_float, + ) + serializer.write_double( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredDouble" + ], + self.required_double, + ) + _serialize_required_string_map( + serializer, + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredMap" + ], + self.required_map, + ) + serializer.write_string( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredEnum" + ], + self.required_enum, + ) + serializer.write_integer( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredIntEnum" + ], + self.required_int_enum, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["required_string"] = de.read_string( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredString" + ] + ) + + case 1: + kwargs["required_boolean"] = de.read_boolean( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredBoolean" + ] + ) + + case 2: + kwargs["required_list"] = _deserialize_required_string_list( + de, + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredList" + ], + ) + + case 3: + kwargs["required_timestamp"] = de.read_timestamp( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredTimestamp" + ] + ) + + case 4: + kwargs["required_blob"] = de.read_blob( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredBlob" + ] + ) + + case 5: + kwargs["required_byte"] = de.read_byte( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredByte" + ] + ) + + case 6: + kwargs["required_short"] = de.read_short( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredShort" + ] + ) + + case 7: + kwargs["required_integer"] = de.read_integer( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredInteger" + ] + ) + + case 8: + kwargs["required_long"] = de.read_long( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredLong" + ] + ) + + case 9: + kwargs["required_float"] = de.read_float( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredFloat" + ] + ) + + case 10: + kwargs["required_double"] = de.read_double( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredDouble" + ] + ) + + case 11: + kwargs["required_map"] = _deserialize_required_string_map( + de, + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredMap" + ], + ) + + case 12: + kwargs["required_enum"] = RequiredEnum( + de.read_string( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredEnum" + ] + ) + ) + + case 13: + kwargs["required_int_enum"] = RequiredIntEnum( + de.read_integer( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT.members[ + "requiredIntEnum" + ] + ) + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT, + consumer=_consumer, + ) + return kwargs + + +OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS = APIOperation( + input=OperationWithRequiredMembersWithDefaultsInput, + output=OperationWithRequiredMembersWithDefaultsOutput, + schema=_SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS, + input_schema=_SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_INPUT, + output_schema=_SCHEMA_OPERATION_WITH_REQUIRED_MEMBERS_WITH_DEFAULTS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class PutWithContentEncodingInput: + """Dataclass for PutWithContentEncodingInput structure.""" + + encoding: str | None = None + + data: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.encoding is not None: + serializer.write_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["encoding"], + self.encoding, + ) + + if self.data is not None: + serializer.write_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["data"], self.data + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["encoding"] = de.read_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["encoding"] + ) + + case 1: + kwargs["data"] = de.read_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class PutWithContentEncodingOutput: + """Dataclass for PutWithContentEncodingOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, consumer=_consumer + ) + return kwargs + + +PUT_WITH_CONTENT_ENCODING = APIOperation( + input=PutWithContentEncodingInput, + output=PutWithContentEncodingOutput, + schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING, + input_schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, + output_schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class QueryIncompatibleOperationInput: + """Dataclass for QueryIncompatibleOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_INCOMPATIBLE_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_QUERY_INCOMPATIBLE_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class QueryIncompatibleOperationOutput: + """Dataclass for QueryIncompatibleOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_INCOMPATIBLE_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_QUERY_INCOMPATIBLE_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +QUERY_INCOMPATIBLE_OPERATION = APIOperation( + input=QueryIncompatibleOperationInput, + output=QueryIncompatibleOperationOutput, + schema=_SCHEMA_QUERY_INCOMPATIBLE_OPERATION, + input_schema=_SCHEMA_QUERY_INCOMPATIBLE_OPERATION_INPUT, + output_schema=_SCHEMA_QUERY_INCOMPATIBLE_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class SimpleScalarPropertiesInput: + """Dataclass for SimpleScalarPropertiesInput structure.""" + + float_value: float | None = None + + double_value: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.float_value is not None: + serializer.write_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["floatValue"], + self.float_value, + ) + + if self.double_value is not None: + serializer.write_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["doubleValue"], + self.double_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["float_value"] = de.read_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["floatValue"] + ) + + case 1: + kwargs["double_value"] = de.read_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["doubleValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class SimpleScalarPropertiesOutput: + """Dataclass for SimpleScalarPropertiesOutput structure.""" + + float_value: float | None = None + + double_value: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.float_value is not None: + serializer.write_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["floatValue"], + self.float_value, + ) + + if self.double_value is not None: + serializer.write_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["doubleValue"], + self.double_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["float_value"] = de.read_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["floatValue"] + ) + + case 1: + kwargs["double_value"] = de.read_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["doubleValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, consumer=_consumer + ) + return kwargs + + +SIMPLE_SCALAR_PROPERTIES = APIOperation( + input=SimpleScalarPropertiesInput, + output=SimpleScalarPropertiesOutput, + schema=_SCHEMA_SIMPLE_SCALAR_PROPERTIES, + input_schema=_SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, + output_schema=_SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) diff --git a/codegen-output/aws-json-1-0/src/awsjson10/user_agent.py b/codegen-output/aws-json-1-0/src/awsjson10/user_agent.py new file mode 100644 index 000000000..9afe74582 --- /dev/null +++ b/codegen-output/aws-json-1-0/src/awsjson10/user_agent.py @@ -0,0 +1,17 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from smithy_aws_core.interceptors.user_agent import UserAgentInterceptor + +from . import __version__ +from .config import AsyncJSONRPC10Config + + +def aws_user_agent_plugin(config: AsyncJSONRPC10Config): + config.interceptors.append( + UserAgentInterceptor( + ua_suffix=config.user_agent_extra, + ua_app_id=config.sdk_ua_app_id, + sdk_version=__version__, + service_id="JSON_RPC_10", + ) + ) diff --git a/codegen-output/aws-json-1-0/tests/__init__.py b/codegen-output/aws-json-1-0/tests/__init__.py new file mode 100644 index 000000000..247be3e3d --- /dev/null +++ b/codegen-output/aws-json-1-0/tests/__init__.py @@ -0,0 +1 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. diff --git a/codegen-output/aws-json-1-0/tests/test_awsjson10_protocol.py b/codegen-output/aws-json-1-0/tests/test_awsjson10_protocol.py new file mode 100644 index 000000000..99bba4110 --- /dev/null +++ b/codegen-output/aws-json-1-0/tests/test_awsjson10_protocol.py @@ -0,0 +1,3734 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from datetime import datetime, timezone +import json +from urllib.parse import parse_qsl + +from pytest import fail, mark, raises +from smithy_aws_core.identity import StaticCredentialsResolver +from smithy_core.aio.retries import SimpleRetryStrategy +from smithy_core.aio.types import AsyncBytesReader +from smithy_core.aio.utils import async_list +from smithy_core.documents import Document +from smithy_http import tuples_to_fields +from smithy_http.aio import HTTPResponse as _smithy_http_aio_HTTPResponse +from smithy_http.aio.interfaces import ( + HTTPRequest, + HTTPResponse as _smithy_http_aio_interfaces_HTTPResponse, +) +from smithy_http.interfaces import HTTPClientConfiguration, HTTPRequestConfiguration + +from awsjson10.client import AsyncJSONRPC10Client +from awsjson10.config import AsyncJSONRPC10Config +from awsjson10.models import ( + ClientOptionalDefaults, + Defaults, + Dialog, + EmptyInputAndEmptyOutputInput, + EmptyInputAndEmptyOutputOutput, + EndpointOperationInput, + EndpointWithHostLabelOperationInput, + Farewell, + GreetingStruct, + GreetingWithErrorsInput, + HostWithPathOperationInput, + JsonUnionsInput, + JsonUnionsOutput, + MyUnionBlobValue, + MyUnionBooleanValue, + MyUnionEnumValue, + MyUnionIntEnumValue, + MyUnionListValue, + MyUnionMapValue, + MyUnionNumberValue, + MyUnionStringValue, + MyUnionStructureValue, + MyUnionTimestampValue, + NoInputAndNoOutputInput, + NoInputAndNoOutputOutput, + NoInputAndOutputInput, + NoInputAndOutputOutput, + OperationWithDefaultsInput, + OperationWithDefaultsOutput, + OperationWithNestedStructureInput, + OperationWithNestedStructureOutput, + OperationWithRequiredMembersInput, + OperationWithRequiredMembersOutput, + OperationWithRequiredMembersWithDefaultsInput, + OperationWithRequiredMembersWithDefaultsOutput, + PutWithContentEncodingInput, + QueryIncompatibleOperationInput, + ServiceError, + SimpleScalarPropertiesInput, + SimpleScalarPropertiesOutput, + TopLevel, +) + + +async def test_aws_json10_empty_input_and_empty_output_request_empty_input_and_empty_output() -> ( + None +): + """Clients must always send an empty object if input is modeled.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyInputAndEmptyOutputInput() + + try: + await client.empty_input_and_empty_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.EmptyInputAndEmptyOutput"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_empty_input_and_empty_output_send_json_object_response_empty_input_and_empty_output() -> ( + None +): + """ + A service will always return a JSON object for operations with modeled + output. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyInputAndEmptyOutputInput() + + try: + actual = await client.empty_input_and_empty_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = EmptyInputAndEmptyOutputOutput() + + assert actual == expected + + +@mark.xfail() +async def test_aws_json10_endpoint_trait_request_endpoint_operation() -> None: + """ + Operations can prepend to the given host if they define the endpoint + trait. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EndpointOperationInput() + + try: + await client.endpoint_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "foo.example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_json10_endpoint_trait_with_host_label_request_endpoint_with_host_label_operation() -> ( + None +): + """ + Operations can prepend to the given host if they define the endpoint + trait, and can use the host label trait to define further customization + based on user input. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EndpointWithHostLabelOperationInput(label="bar") + + try: + await client.endpoint_with_host_label_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "foo.bar.example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"label": "bar"}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_invalid_greeting_error_error_greeting_with_errors() -> None: + """Parses simple JSON errors""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=400, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "__type": "aws.protocoltests.json10#InvalidGreeting",\n "Message": "Hi"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'InvalidGreeting' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "InvalidGreeting": + fail( + f"Expected 'InvalidGreeting' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_complex_error_error_greeting_with_errors() -> None: + """Parses a complex error with no message member""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=400, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "__type": "aws.protocoltests.json10#ComplexError",\n "TopLevel": "Top level",\n "Nested": {\n "Foo": "bar"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'ComplexError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "ComplexError": + fail( + f"Expected 'ComplexError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_empty_complex_error_error_greeting_with_errors() -> None: + """Parses a complex error with an empty body""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=400, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "__type": "aws.protocoltests.json10#ComplexError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'ComplexError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "ComplexError": + fail( + f"Expected 'ComplexError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_using_x_amzn_error_type_error_greeting_with_errors() -> ( + None +): + """ + Serializes the X-Amzn-ErrorType header. For an example service, see + Amazon EKS. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, headers=[("X-Amzn-Errortype", "FooError")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_using_x_amzn_error_type_with_uri_error_greeting_with_errors() -> ( + None +): + """ + Some X-Amzn-Errortype headers contain URLs. Clients need to split the + URL on ':' and take only the first half of the string. For example, + 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/' + is to be interpreted as 'ValidationException'. For an example service + see Amazon Polly. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[ + ( + "X-Amzn-Errortype", + "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/", + ) + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_using_x_amzn_error_type_with_uri_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + X-Amzn-Errortype might contain a URL and a namespace. Client should + extract only the shape name. This is a pathalogical case that might not + actually happen in any deployed AWS service. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[ + ( + "X-Amzn-Errortype", + "aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/", + ) + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_using_code_error_greeting_with_errors() -> None: + """ + This example uses the 'code' property in the output rather than + X-Amzn-Errortype. Some services do this though it's preferable to send + the X-Amzn-Errortype. Client implementations must first check for the + X-Amzn-Errortype and then check for a top-level 'code' property. For + example service see Amazon S3 Glacier. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "code": "FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_using_code_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using code, and it might contain a + namespace. Clients should just take the last part of the string after + '#'. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "code": "aws.protocoltests.json10#FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_using_code_uri_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using code, and it might contain a + namespace. It also might contain a URI. Clients should just take the + last part of the string after '#' and before \":\". This is a + pathalogical case that might not occur in any deployed AWS service. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "code": "aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_with_dunder_type_error_greeting_with_errors() -> ( + None +): + """Some services serialize errors using __type.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "__type": "FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_with_dunder_type_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using __type, and it might contain a + namespace. Clients should just take the last part of the string after + '#'. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "__type": "aws.protocoltests.json10#FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_with_dunder_type_and_different_namespace_error_greeting_with_errors() -> ( + None +): + """ + Because only the part after '#' is considered, an unrecognized + namespace should not make a difference. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "__type": "aws.different.namespace#FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_with_dunder_type_uri_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using __type, and it might contain a + namespace. It also might contain a URI. Clients should just take the + last part of the string after '#' and before \":\". This is a + pathalogical case that might not occur in any deployed AWS service. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "__type": "aws.protocoltests.json10#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_foo_error_with_nested_type_property_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using __type, and if the response + includes additional shapes that belong to a different namespace + there'll be a nested __type property that must not be considered when + determining which error to be surfaced. For an example service see + Amazon DynamoDB. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "__type": "aws.protocoltests.json10#FooError",\n "ErrorDetails": [\n {\n "__type": "com.amazon.internal#ErrorDetails",\n "reason": "Some reason"\n }\n ]\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_host_with_path_request_host_with_path_operation() -> None: + """Custom endpoints supplied by users can have paths""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/custom", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HostWithPathOperationInput() + + try: + await client.host_with_path_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/custom/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_string_union_value_request_json_unions() -> None: + """Serializes a string union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionStringValue(value="foo")) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "stringValue": "foo"\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_boolean_union_value_request_json_unions() -> None: + """Serializes a boolean union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionBooleanValue(value=True)) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "booleanValue": true\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_number_union_value_request_json_unions() -> None: + """Serializes a number union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionNumberValue(value=1)) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "numberValue": 1\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_blob_union_value_request_json_unions() -> None: + """Serializes a blob union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionBlobValue(value=b"foo")) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "blobValue": "Zm9v"\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_timestamp_union_value_request_json_unions() -> None: + """Serializes a timestamp union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionTimestampValue( + value=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "timestampValue": 1398796238\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_enum_union_value_request_json_unions() -> None: + """Serializes an enum union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionEnumValue(value="Foo")) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "enumValue": "Foo"\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_int_enum_union_value_request_json_unions() -> None: + """Serializes an intEnum union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionIntEnumValue(value=1)) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "intEnumValue": 1\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_list_union_value_request_json_unions() -> None: + """Serializes a list union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionListValue(value=["foo", "bar"])) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_map_union_value_request_json_unions() -> None: + """Serializes a map union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionMapValue(value={"foo": "bar", "spam": "eggs"}) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_serialize_structure_union_value_request_json_unions() -> None: + """Serializes a structure union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_deserialize_string_union_value_response_json_unions() -> None: + """Deserializes a string union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "stringValue": "foo"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionStringValue(value="foo")) + + assert actual == expected + + +async def test_aws_json10_deserialize_boolean_union_value_response_json_unions() -> ( + None +): + """Deserializes a boolean union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "booleanValue": true\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionBooleanValue(value=True)) + + assert actual == expected + + +async def test_aws_json10_deserialize_number_union_value_response_json_unions() -> None: + """Deserializes a number union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "numberValue": 1\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionNumberValue(value=1)) + + assert actual == expected + + +async def test_aws_json10_deserialize_blob_union_value_response_json_unions() -> None: + """Deserializes a blob union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "blobValue": "Zm9v"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionBlobValue(value=b"foo")) + + assert actual == expected + + +async def test_aws_json10_deserialize_timestamp_union_value_response_json_unions() -> ( + None +): + """Deserializes a timestamp union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "timestampValue": 1398796238\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionTimestampValue( + value=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + ) + + assert actual == expected + + +async def test_aws_json10_deserialize_enum_union_value_response_json_unions() -> None: + """Deserializes an enum union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "enumValue": "Foo"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionEnumValue(value="Foo")) + + assert actual == expected + + +async def test_aws_json10_deserialize_int_enum_union_value_response_json_unions() -> ( + None +): + """Deserializes an intEnum union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "intEnumValue": 1\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionIntEnumValue(value=1)) + + assert actual == expected + + +async def test_aws_json10_deserialize_list_union_value_response_json_unions() -> None: + """Deserializes a list union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionListValue(value=["foo", "bar"])) + + assert actual == expected + + +async def test_aws_json10_deserialize_map_union_value_response_json_unions() -> None: + """Deserializes a map union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionMapValue(value={"foo": "bar", "spam": "eggs"}) + ) + + assert actual == expected + + +async def test_aws_json10_deserialize_structure_union_value_response_json_unions() -> ( + None +): + """Deserializes a structure union value""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + assert actual == expected + + +async def test_aws_json10_deserialize_ignore_type_response_json_unions() -> None: + """Ignores an unrecognized __type property""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "__type": "aws.protocoltests.json10#MyUnion",\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + assert actual == expected + + +async def test_aws_json10_deserialize_allow_nulls_response_json_unions() -> None: + """Allows for `: null` to be set for all unset fields""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "contents": {\n "stringValue": null,\n "booleanValue": null,\n "numberValue": null,\n "blobValue": null,\n "timestampValue": null,\n "enumValue": null,\n "intEnumValue": null,\n "listValue": null,\n "mapValue": null,\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + assert actual == expected + + +async def test_aws_json10_must_always_send_empty_json_payload_request_no_input_and_no_output() -> ( + None +): + """ + Clients must always send an empty JSON object payload for operations + with no input (that is, `{}`). While AWS service implementations + support requests with no payload or requests that send `{}`, always + sending `{}` from the client is preferred for forward compatibility in + case input is ever added to an operation. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndNoOutputInput() + + try: + await client.no_input_and_no_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.NoInputAndNoOutput"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_handles_empty_output_shape_response_no_input_and_no_output() -> ( + None +): + """ + When no output is defined, the service is expected to return an empty + payload, however, client must ignore a JSON payload if one is returned. + This ensures that if output is added later, then it will not break the + client. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndNoOutputInput() + + try: + actual = await client.no_input_and_no_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndNoOutputOutput() + + assert actual == expected + + +async def test_aws_json10_handles_unexpected_json_output_response_no_input_and_no_output() -> ( + None +): + """ + This client-only test builds on handles_empty_output_shape, by including + unexpected fields in the JSON. A client needs to ignore JSON output that + is empty or that contains JSON object data. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "foo": true\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndNoOutputInput() + + try: + actual = await client.no_input_and_no_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndNoOutputOutput() + + assert actual == expected + + +async def test_aws_json10_service_responds_with_no_payload_response_no_input_and_no_output() -> ( + None +): + """ + When no output is defined, the service is expected to return an empty + payload. Despite the lack of a payload, the service is expected to + always send a Content-Type header. Clients must handle cases where a + service returns a JSON object and where a service returns no JSON at + all. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndNoOutputInput() + + try: + actual = await client.no_input_and_no_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndNoOutputOutput() + + assert actual == expected + + +async def test_aws_json10_no_input_and_output_request_no_input_and_output() -> None: + """A client should always send and empty JSON object payload.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndOutputInput() + + try: + await client.no_input_and_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.NoInputAndOutput"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_no_input_and_output_response_no_input_and_output() -> None: + """Empty output always serializes an empty object payload.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndOutputInput() + + try: + actual = await client.no_input_and_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndOutputOutput() + + assert actual == expected + + +@mark.xfail() +async def test_aws_json10_client_populates_default_values_in_input_request_operation_with_defaults() -> ( + None +): + """Client populates default values in input.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput(defaults=Defaults()) + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "defaults": {\n "defaultString": "hi",\n "defaultBoolean": true,\n "defaultList": [],\n "defaultDocumentMap": {},\n "defaultDocumentString": "hi",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": [],\n "defaultTimestamp": 0,\n "defaultBlob": "YWJj",\n "defaultByte": 1,\n "defaultShort": 1,\n "defaultInteger": 10,\n "defaultLong": 100,\n "defaultFloat": 1.0,\n "defaultDouble": 1.0,\n "defaultMap": {},\n "defaultEnum": "FOO",\n "defaultIntEnum": 1,\n "emptyString": "",\n "falseBoolean": false,\n "emptyBlob": "",\n "zeroByte": 0,\n "zeroShort": 0,\n "zeroInteger": 0,\n "zeroLong": 0,\n "zeroFloat": 0.0,\n "zeroDouble": 0.0\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_json10_client_skips_top_level_default_values_in_input_request_operation_with_defaults() -> ( + None +): + """Client skips top level default values in input.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput() + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{\n}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_json10_client_uses_explicitly_provided_member_values_over_defaults_request_operation_with_defaults() -> ( + None +): + """Client uses explicitly provided member values over defaults""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput( + defaults=Defaults( + default_string="bye", + default_boolean=True, + default_list=["a"], + default_document_map=Document({"name": "Jack"}), + default_document_string=Document("bye"), + default_document_boolean=Document(True), + default_document_list=Document(["b"]), + default_null_document=Document("notNull"), + default_timestamp=datetime(1970, 1, 1, 0, 0, 1, 0, timezone.utc), + default_blob=b"hi", + default_byte=2, + default_short=2, + default_integer=20, + default_long=200, + default_float=float(2.0), + default_double=float(2.0), + default_map={"name": "Jack"}, + default_enum="BAR", + default_int_enum=2, + empty_string="foo", + false_boolean=True, + empty_blob=b"hi", + zero_byte=1, + zero_short=1, + zero_integer=1, + zero_long=1, + zero_float=float(1.0), + zero_double=float(1.0), + ) + ) + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "defaults": {\n "defaultString": "bye",\n "defaultBoolean": true,\n "defaultList": ["a"],\n "defaultDocumentMap": {"name": "Jack"},\n "defaultDocumentString": "bye",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": ["b"],\n "defaultNullDocument": "notNull",\n "defaultTimestamp": 1,\n "defaultBlob": "aGk=",\n "defaultByte": 2,\n "defaultShort": 2,\n "defaultInteger": 20,\n "defaultLong": 200,\n "defaultFloat": 2.0,\n "defaultDouble": 2.0,\n "defaultMap": {"name": "Jack"},\n "defaultEnum": "BAR",\n "defaultIntEnum": 2,\n "emptyString": "foo",\n "falseBoolean": true,\n "emptyBlob": "aGk=",\n "zeroByte": 1,\n "zeroShort": 1,\n "zeroInteger": 1,\n "zeroLong": 1,\n "zeroFloat": 1.0,\n "zeroDouble": 1.0\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_client_uses_explicitly_provided_values_in_top_level_request_operation_with_defaults() -> ( + None +): + """ + Any time a value is provided for a member in the top level of input, it + is used, regardless of if its the default. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput( + top_level_default="hi", other_top_level_default=0 + ) + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "topLevelDefault": "hi",\n "otherTopLevelDefault": 0\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_json10_client_ignores_non_top_level_defaults_on_members_with_client_optional_request_operation_with_defaults() -> ( + None +): + """ + Typically, non top-level members would have defaults filled in, but if + they have the clientOptional trait, the defaults should be ignored. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput( + client_optional_defaults=ClientOptionalDefaults() + ) + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "clientOptionalDefaults": {}\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_client_populates_defaults_values_when_missing_in_response_response_operation_with_defaults() -> ( + None +): + """Client populates default values when missing in response.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput() + + try: + actual = await client.operation_with_defaults(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = OperationWithDefaultsOutput( + default_string="hi", + default_boolean=True, + default_list=[], + default_document_map=Document({}), + default_document_string=Document("hi"), + default_document_boolean=Document(True), + default_document_list=Document([]), + default_timestamp=datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc), + default_blob=b"abc", + default_byte=1, + default_short=1, + default_integer=10, + default_long=100, + default_float=float(1.0), + default_double=float(1.0), + default_map={}, + default_enum="FOO", + default_int_enum=1, + empty_string="", + false_boolean=False, + empty_blob=b"", + zero_byte=0, + zero_short=0, + zero_integer=0, + zero_long=0, + zero_float=float(0.0), + zero_double=float(0.0), + ) + + assert actual == expected + + +async def test_aws_json10_client_ignores_default_values_if_member_values_are_present_in_response_response_operation_with_defaults() -> ( + None +): + """ + Client ignores default values if member values are present in the + response. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "defaultString": "bye",\n "defaultBoolean": false,\n "defaultList": ["a"],\n "defaultDocumentMap": {"name": "Jack"},\n "defaultDocumentString": "bye",\n "defaultDocumentBoolean": false,\n "defaultDocumentList": ["b"],\n "defaultNullDocument": "notNull",\n "defaultTimestamp": 2,\n "defaultBlob": "aGk=",\n "defaultByte": 2,\n "defaultShort": 2,\n "defaultInteger": 20,\n "defaultLong": 200,\n "defaultFloat": 2.0,\n "defaultDouble": 2.0,\n "defaultMap": {"name": "Jack"},\n "defaultEnum": "BAR",\n "defaultIntEnum": 2,\n "emptyString": "foo",\n "falseBoolean": true,\n "emptyBlob": "aGk=",\n "zeroByte": 1,\n "zeroShort": 1,\n "zeroInteger": 1,\n "zeroLong": 1,\n "zeroFloat": 1.0,\n "zeroDouble": 1.0\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput() + + try: + actual = await client.operation_with_defaults(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = OperationWithDefaultsOutput( + default_string="bye", + default_boolean=False, + default_list=["a"], + default_document_map=Document({"name": "Jack"}), + default_document_string=Document("bye"), + default_document_boolean=Document(False), + default_document_list=Document(["b"]), + default_null_document=Document("notNull"), + default_timestamp=datetime(1970, 1, 1, 0, 0, 2, 0, timezone.utc), + default_blob=b"hi", + default_byte=2, + default_short=2, + default_integer=20, + default_long=200, + default_float=float(2.0), + default_double=float(2.0), + default_map={"name": "Jack"}, + default_enum="BAR", + default_int_enum=2, + empty_string="foo", + false_boolean=True, + empty_blob=b"hi", + zero_byte=1, + zero_short=1, + zero_integer=1, + zero_long=1, + zero_float=float(1.0), + zero_double=float(1.0), + ) + + assert actual == expected + + +async def test_aws_json10_client_populates_nested_default_values_when_missing_request_operation_with_nested_structure() -> ( + None +): + """Client populates nested default values when missing.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithNestedStructureInput( + top_level=TopLevel( + dialog=Dialog(language="en"), + dialog_list=[ + Dialog(), + Dialog(farewell=Farewell()), + Dialog( + language="it", + greeting="ciao", + farewell=Farewell(phrase="arrivederci"), + ), + ], + dialog_map={ + "emptyDialog": Dialog(), + "partialEmptyDialog": Dialog(language="en", farewell=Farewell()), + "nonEmptyDialog": Dialog( + greeting="konnichiwa", farewell=Farewell(phrase="sayonara") + ), + }, + ) + ) + + try: + await client.operation_with_nested_structure(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "topLevel": {\n "dialog": {\n "language": "en",\n "greeting": "hi"\n },\n "dialogList": [\n {\n "greeting": "hi"\n },\n {\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n "greeting": "hi"\n },\n "partialEmptyDialog": {\n "language": "en",\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_client_populates_nested_defaults_when_missing_in_response_body_response_operation_with_nested_structure() -> ( + None +): + """Client populates nested default values when missing in response body.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "dialog": {\n "language": "en"\n },\n "dialogList": [\n {\n },\n {\n "farewell": {}\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n },\n "partialEmptyDialog": {\n "language": "en",\n "farewell": {}\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithNestedStructureInput() + + try: + actual = await client.operation_with_nested_structure(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = OperationWithNestedStructureOutput( + dialog=Dialog(language="en", greeting="hi"), + dialog_list=[ + Dialog(greeting="hi"), + Dialog(greeting="hi", farewell=Farewell(phrase="bye")), + Dialog( + language="it", + greeting="ciao", + farewell=Farewell(phrase="arrivederci"), + ), + ], + dialog_map={ + "emptyDialog": Dialog(greeting="hi"), + "partialEmptyDialog": Dialog( + language="en", greeting="hi", farewell=Farewell(phrase="bye") + ), + "nonEmptyDialog": Dialog( + greeting="konnichiwa", farewell=Farewell(phrase="sayonara") + ), + }, + ) + + assert actual == expected + + +async def test_aws_json10_client_error_corrects_when_server_fails_to_serialize_required_values_response_operation_with_required_members() -> ( + None +): + """Client error corrects when server fails to serialize required values.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithRequiredMembersInput() + + try: + actual = await client.operation_with_required_members(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = OperationWithRequiredMembersOutput( + required_string="", + required_boolean=False, + required_list=[], + required_timestamp=datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc), + required_blob=b"", + required_byte=0, + required_short=0, + required_integer=0, + required_long=0, + required_float=float(0.0), + required_double=float(0.0), + required_map={}, + ) + + assert actual == expected + + +async def test_aws_json10_client_error_corrects_with_default_values_when_server_fails_to_serialize_required_values_response_operation_with_required_members_with_defaults() -> ( + None +): + """ + Client error corrects with default values when server fails to serialize + required values. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithRequiredMembersWithDefaultsInput() + + try: + actual = await client.operation_with_required_members_with_defaults(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = OperationWithRequiredMembersWithDefaultsOutput( + required_string="hi", + required_boolean=True, + required_list=[], + required_timestamp=datetime(1970, 1, 1, 0, 0, 1, 0, timezone.utc), + required_blob=b"blob", + required_byte=1, + required_short=1, + required_integer=10, + required_long=100, + required_float=float(1.0), + required_double=float(1.0), + required_map={}, + required_enum="FOO", + required_int_enum=1, + ) + + assert actual == expected + + +@mark.xfail() +async def test_sdk_applied_content_encoding_aws_json1_0_request_put_with_content_encoding() -> ( + None +): + """ + Compression algorithm encoding is appended to the Content-Encoding + header. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutWithContentEncodingInput( + data="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\n" + ) + + try: + await client.put_with_content_encoding(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-encoding", "gzip")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_sdk_appends_gzip_and_ignores_http_provided_encoding_aws_json1_0_request_put_with_content_encoding() -> ( + None +): + """ + Compression algorithm encoding is appended to the Content-Encoding + header, and the user-provided content-encoding is NOT in the + Content-Encoding header since HTTP binding traits are ignored in the + awsJson1_0 protocol. + """ + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutWithContentEncodingInput( + encoding="custom", + data="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\n", + ) + + try: + await client.put_with_content_encoding(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-encoding", "gzip")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_non_query_compatible_aws_json10_forbids_query_mode_header_request_query_incompatible_operation() -> ( + None +): + """The query mode header MUST NOT be set on non-query-compatible services.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryIncompatibleOperationInput() + + try: + await client.query_incompatible_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.QueryIncompatibleOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_json10_supports_na_n_float_inputs_request_simple_scalar_properties() -> ( + None +): + """Supports handling NaN float values.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + float_value=float("nan"), double_value=float("nan") + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.SimpleScalarProperties"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "floatValue": "NaN",\n "doubleValue": "NaN"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_supports_infinity_float_inputs_request_simple_scalar_properties() -> ( + None +): + """Supports handling Infinity float values.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + float_value=float("inf"), double_value=float("inf") + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.SimpleScalarProperties"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "floatValue": "Infinity",\n "doubleValue": "Infinity"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json10_supports_negative_infinity_float_inputs_request_simple_scalar_properties() -> ( + None +): + """Supports handling -Infinity float values.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + float_value=float("-inf"), double_value=float("-inf") + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.0"), + ("x-amz-target", "JsonRpc10.SimpleScalarProperties"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "floatValue": "-Infinity",\n "doubleValue": "-Infinity"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_json10_supports_na_n_float_inputs_response_simple_scalar_properties() -> ( + None +): + """Supports handling NaN float values.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "floatValue": "NaN",\n "doubleValue": "NaN"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + float_value=float("nan"), double_value=float("nan") + ) + + assert actual == expected + + +async def test_aws_json10_supports_infinity_float_inputs_response_simple_scalar_properties() -> ( + None +): + """Supports handling Infinity float values.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "floatValue": "Infinity",\n "doubleValue": "Infinity"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + float_value=float("inf"), double_value=float("inf") + ) + + assert actual == expected + + +async def test_aws_json10_supports_negative_infinity_float_inputs_response_simple_scalar_properties() -> ( + None +): + """Supports handling -Infinity float values.""" + client = AsyncJSONRPC10Client( + config=await AsyncJSONRPC10Config.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.0")], + body=b'{\n "floatValue": "-Infinity",\n "doubleValue": "-Infinity"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + float_value=float("-inf"), double_value=float("-inf") + ) + + assert actual == expected + + +class TestHttpServiceError(ServiceError): + """A test error that subclasses the service-error for protocol tests.""" + + def __init__(self, request: HTTPRequest): + self.request = request + + +class RequestTestHTTPClient: + """An asynchronous HTTP client solely for testing purposes.""" + + TIMEOUT_EXCEPTIONS = () + SUPPORTS_DUPLEX_STREAMING: bool = True + + def __init__(self, *, client_config: HTTPClientConfiguration | None = None): + self._client_config = client_config + + async def send( + self, + request: HTTPRequest, + *, + request_config: HTTPRequestConfiguration | None = None, + ) -> _smithy_http_aio_interfaces_HTTPResponse: + # Raise the exception with the request object to bypass actual request handling + raise TestHttpServiceError(request) + + +class ResponseTestHTTPClient: + """An asynchronous HTTP client solely for testing purposes.""" + + TIMEOUT_EXCEPTIONS = () + SUPPORTS_DUPLEX_STREAMING: bool = True + + def __init__( + self, + *, + client_config: HTTPClientConfiguration | None = None, + status: int = 200, + headers: list[tuple[str, str]] | None = None, + body: bytes = b"", + ): + self._client_config = client_config + self.status = status + self.fields = tuples_to_fields(headers or []) + self.body = body + + async def send( + self, + request: HTTPRequest, + *, + request_config: HTTPRequestConfiguration | None = None, + ) -> _smithy_http_aio_HTTPResponse: + # Pre-construct the response from the request and return it + return _smithy_http_aio_HTTPResponse( + status=self.status, fields=self.fields, body=async_list([self.body]) + ) diff --git a/codegen-output/aws-json-1-1/README.md b/codegen-output/aws-json-1-1/README.md new file mode 100644 index 000000000..b23ba22a6 --- /dev/null +++ b/codegen-output/aws-json-1-1/README.md @@ -0,0 +1,5 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +## Sample Json 1.1 Protocol Service Client + +awsjson11 client diff --git a/codegen-output/aws-json-1-1/pyproject.toml b/codegen-output/aws-json-1-1/pyproject.toml new file mode 100644 index 000000000..6119590da --- /dev/null +++ b/codegen-output/aws-json-1-1/pyproject.toml @@ -0,0 +1,66 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +[project] +name = "awsjson11" +version = "0.0.1" +description = "awsjson11 client" +readme = "README.md" +requires-python = ">=3.12" +keywords = ["smithy", "awsjson11"] +license = {text = "Apache-2.0"} +classifiers = [ + "Development Status :: 2 - Pre-Alpha", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Natural Language :: English", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14" +] + +dependencies = [ + "smithy_aws_core[json]~=0.11.0", + "smithy_core~=0.8.0", + "smithy_http[aiohttp]~=0.5.0" +] + +[project.optional-dependencies] +awscrt = [ + "smithy_http[awscrt]~=0.5.0" +] + +[dependency-groups] +test = [ + "pytest>=9.0.1,<10.0.0", + "pytest-asyncio>=1.3.0,<1.4.0" +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.pyright] +typeCheckingMode = "strict" +reportPrivateUsage = false +reportUnusedFunction = false +reportUnusedVariable = false +reportUnnecessaryComparison = false +reportUnusedClass = false +enableExperimentalFeatures = true + +[tool.ruff] +target-version = "py312" + +[tool.ruff.lint] +ignore = ["F841"] + +[tool.ruff.format] +skip-magic-trailing-comma = true + +[tool.pytest.ini_options] +python_classes = ["!Test"] +asyncio_mode = "auto" diff --git a/codegen-output/aws-json-1-1/src/awsjson11/__init__.py b/codegen-output/aws-json-1-1/src/awsjson11/__init__.py new file mode 100644 index 000000000..30f6d44e9 --- /dev/null +++ b/codegen-output/aws-json-1-1/src/awsjson11/__init__.py @@ -0,0 +1,3 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +__version__: str = "0.0.1" diff --git a/codegen-output/aws-json-1-1/src/awsjson11/_private/__init__.py b/codegen-output/aws-json-1-1/src/awsjson11/_private/__init__.py new file mode 100644 index 000000000..247be3e3d --- /dev/null +++ b/codegen-output/aws-json-1-1/src/awsjson11/_private/__init__.py @@ -0,0 +1 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. diff --git a/codegen-output/aws-json-1-1/src/awsjson11/_private/schemas.py b/codegen-output/aws-json-1-1/src/awsjson11/_private/schemas.py new file mode 100644 index 000000000..7f2d53d63 --- /dev/null +++ b/codegen-output/aws-json-1-1/src/awsjson11/_private/schemas.py @@ -0,0 +1,3551 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from types import MappingProxyType + +from smithy_core.prelude import ( + BLOB, + BOOLEAN, + DOUBLE, + FLOAT, + INTEGER, + LONG, + STRING, + TIMESTAMP, + UNIT, +) +from smithy_core.schemas import Schema +from smithy_core.shapes import ShapeID, ShapeType +from smithy_core.traits import Trait + + +COMPLEX_NESTED_ERROR_DATA = Schema.collection( + id=ShapeID("aws.protocoltests.json#ComplexNestedErrorData"), + members={ + "Foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#jsonName"), value="Fooooo")], + } + }, +) + +COMPLEX_ERROR = Schema.collection( + id=ShapeID("aws.protocoltests.json#ComplexError"), + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11ComplexError", + "documentation": "Parses a complex error with no message member", + "protocol": "aws.protocols#awsJson1_1", + "params": MappingProxyType( + { + "TopLevel": "Top level", + "Nested": MappingProxyType({"Foo": "bar"}), + } + ), + "code": 400, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "__type": "ComplexError",\n "TopLevel": "Top level",\n "Nested": {\n "Foo": "bar"\n }\n}', + "bodyMediaType": "application/json", + } + ), + MappingProxyType( + { + "id": "AwsJson11EmptyComplexError", + "protocol": "aws.protocols#awsJson1_1", + "code": 400, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "__type": "ComplexError"\n}', + "bodyMediaType": "application/json", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="client"), + ], + members={ + "TopLevel": {"target": STRING}, + "Nested": {"target": COMPLEX_NESTED_ERROR_DATA}, + }, +) + +CONTENT_TYPE_PARAMETERS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#ContentTypeParametersInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"value": {"target": INTEGER}}, +) + +CONTENT_TYPE_PARAMETERS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#ContentTypeParametersOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], +) + +CONTENT_TYPE_PARAMETERS = Schema( + id=ShapeID("aws.protocoltests.json#ContentTypeParameters"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11MustSupportParametersInContentType", + "documentation": "A server should ignore parameters added to the content type", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1; charset=utf-8", + "X-Amz-Target": "JsonProtocol.ContentTypeParameters", + } + ), + "uri": "/", + "body": '{"value":5}', + "bodyMediaType": "application/json", + "params": MappingProxyType({"value": 5}), + "appliesTo": "server", + } + ), + ), + ) + ], +) + +DATETIME_OFFSETS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#DatetimeOffsetsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +DATE_TIME = Schema( + id=ShapeID("aws.protocoltests.shared#DateTime"), + shape_type=ShapeType.TIMESTAMP, + traits=[Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time")], +) + +DATETIME_OFFSETS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#DatetimeOffsetsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"datetime": {"target": DATE_TIME}}, +) + +DATETIME_OFFSETS = Schema( + id=ShapeID("aws.protocoltests.json#DatetimeOffsets"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11DateTimeWithNegativeOffset", + "documentation": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": ' {\n "datetime": "2019-12-16T22:48:18-01:00"\n }\n', + "params": MappingProxyType({"datetime": 1576540098}), + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11DateTimeWithPositiveOffset", + "documentation": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": ' {\n "datetime": "2019-12-17T00:48:18+01:00"\n }\n', + "params": MappingProxyType({"datetime": 1576540098}), + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +DOCUMENT = Schema( + id=ShapeID("aws.protocoltests.json#Document"), shape_type=ShapeType.DOCUMENT +) + +EMPTY_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#EmptyOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +EMPTY_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#EmptyOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +EMPTY_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json#EmptyOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "sends_requests_to_slash", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Sends requests to /", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EmptyOperation", + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "includes_x_amz_target_and_content_type", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Includes X-Amz-Target header and Content-Type", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EmptyOperation", + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "json_1_1_client_sends_empty_payload_for_no_input_shape", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Clients must always send an empty JSON object payload for\noperations with no input (that is, `{}`). While AWS service\nimplementations support requests with no payload or requests\nthat send `{}`, always sending `{}` from the client is\npreferred for forward compatibility in case input is ever\nadded to an operation.", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EmptyOperation", + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "json_1_1_service_supports_empty_payload_for_no_input_shape", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Service implementations must support no payload or an empty\nobject payload for operations that define no input. However,\ndespite the lack of a payload, a Content-Type header is still\nrequired in order for the service to properly detect the\nprotocol.", + "body": "", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EmptyOperation", + } + ), + "method": "POST", + "uri": "/", + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "handles_empty_output_shape", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "When no output is defined, the service is expected to return\nan empty payload, however, client must ignore a JSON payload\nif one is returned. This ensures that if output is added later,\nthen it will not break the client.", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "code": 200, + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "handles_unexpected_json_output", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "This client-only test builds on handles_empty_output_shape,\nby including unexpected fields in the JSON. A client\nneeds to ignore JSON output that is empty or that contains\nJSON object data.", + "body": '{\n "foo": true\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "code": 200, + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "json_1_1_service_responds_with_no_payload", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "When no output is defined, the service is expected to return\nan empty payload. Despite the lack of a payload, the service\nis expected to always send a Content-Type header. Clients must\nhandle cases where a service returns a JSON object and where\na service returns no JSON at all.", + "body": "", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "code": 200, + } + ), + ), + ), + ], +) + +EMPTY_STRUCT = Schema.collection(id=ShapeID("aws.protocoltests.json#EmptyStruct")) + +ENDPOINT_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#EndpointOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +ENDPOINT_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#EndpointOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +ENDPOINT_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json#EndpointOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11EndpointTrait", + "documentation": "Operations can prepend to the given host if they define the\nendpoint trait.", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": "{}", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EndpointOperation", + } + ), + "host": "example.com", + "resolvedHost": "foo.example.com", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#endpoint"), + value=MappingProxyType({"hostPrefix": "foo."}), + ), + ], +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#EndpointWithHostLabelOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#HostLabelInput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "label": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#hostLabel")), + Trait.new(id=ShapeID("smithy.api#required")), + ], + } + }, +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#EndpointWithHostLabelOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json#EndpointWithHostLabelOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11EndpointTraitWithHostLabel", + "documentation": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{"label": "bar"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.EndpointWithHostLabelOperation", + } + ), + "host": "example.com", + "resolvedHost": "foo.bar.example.com", + "params": MappingProxyType({"label": "bar"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#endpoint"), + value=MappingProxyType({"hostPrefix": "foo.{label}."}), + ), + ], +) + +JSON_VALUE = Schema( + id=ShapeID("aws.protocoltests.json#JsonValue"), + shape_type=ShapeType.STRING, + traits=[Trait.new(id=ShapeID("smithy.api#mediaType"), value="application/json")], +) + +LIST_OF_STRINGS = Schema.collection( + id=ShapeID("aws.protocoltests.json#ListOfStrings"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING}}, +) + +LIST_OF_LIST_OF_STRINGS = Schema.collection( + id=ShapeID("aws.protocoltests.json#ListOfListOfStrings"), + shape_type=ShapeType.LIST, + members={"member": {"target": LIST_OF_STRINGS}}, +) + +MAP_OF_STRINGS = Schema.collection( + id=ShapeID("aws.protocoltests.json#MapOfStrings"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +LIST_OF_MAPS_OF_STRINGS = Schema.collection( + id=ShapeID("aws.protocoltests.json#ListOfMapsOfStrings"), + shape_type=ShapeType.LIST, + members={"member": {"target": MAP_OF_STRINGS}}, +) + +SIMPLE_STRUCT = Schema.collection( + id=ShapeID("aws.protocoltests.json#SimpleStruct"), + members={"Value": {"target": STRING}}, +) + +LIST_OF_STRUCTS = Schema.collection( + id=ShapeID("aws.protocoltests.json#ListOfStructs"), + shape_type=ShapeType.LIST, + members={"member": {"target": SIMPLE_STRUCT}}, +) + +MAP_OF_LISTS_OF_STRINGS = Schema.collection( + id=ShapeID("aws.protocoltests.json#MapOfListsOfStrings"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": LIST_OF_STRINGS}}, +) + +MAP_OF_MAP_OF_STRINGS = Schema.collection( + id=ShapeID("aws.protocoltests.json#MapOfMapOfStrings"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": MAP_OF_STRINGS}}, +) + +MAP_OF_STRUCTS = Schema.collection( + id=ShapeID("aws.protocoltests.json#MapOfStructs"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": SIMPLE_STRUCT}}, +) + +STRUCT_WITH_JSON_NAME = Schema.collection( + id=ShapeID("aws.protocoltests.json#StructWithJsonName"), + members={ + "Value": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#jsonName"), value="RenamedMember") + ], + } + }, +) + +ERROR_WITHOUT_MEMBERS = Schema.collection( + id=ShapeID("aws.protocoltests.json#ErrorWithoutMembers"), + traits=[Trait.new(id=ShapeID("smithy.api#error"), value="server")], +) + +FOO_ERROR = Schema.collection( + id=ShapeID("aws.protocoltests.json#FooError"), + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11FooErrorUsingXAmznErrorType", + "documentation": "Serializes the X-Amzn-ErrorType header. For an example service, see Amazon EKS.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType({"X-Amzn-Errortype": "FooError"}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorUsingXAmznErrorTypeWithUri", + "documentation": "Some X-Amzn-Errortype headers contain URLs. Clients need to split the URL on ':' and take only the first half of the string. For example, 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/'\nis to be interpreted as 'ValidationException'.\n\nFor an example service see Amazon Polly.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + { + "X-Amzn-Errortype": "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "documentation": "X-Amzn-Errortype might contain a URL and a namespace. Client should extract only the shape name. This is a pathalogical case that might not actually happen in any deployed AWS service.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + { + "X-Amzn-Errortype": "aws.protocoltests.json#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorUsingCode", + "documentation": "This example uses the 'code' property in the output rather than X-Amzn-Errortype. Some services do this though it's preferable to send the X-Amzn-Errortype. Client implementations must first check for the X-Amzn-Errortype and then check for a top-level 'code' property.\n\nFor example service see Amazon S3 Glacier.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "code": "FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorUsingCodeAndNamespace", + "documentation": "Some services serialize errors using code, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "code": "aws.protocoltests.json#FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorUsingCodeUriAndNamespace", + "documentation": "Some services serialize errors using code, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "code": "aws.protocoltests.json#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorWithDunderType", + "documentation": "Some services serialize errors using __type.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "__type": "FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorWithDunderTypeAndNamespace", + "documentation": "Some services serialize errors using __type, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "__type": "aws.protocoltests.json#FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorWithDunderTypeAndDifferentNamespace", + "documentation": "Because only the part after '#' is considered, an unrecognized namespace should not make a difference.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "__type": "aws.different.namespace#FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorWithDunderTypeUriAndNamespace", + "documentation": "Some services serialize errors using __type, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "__type": "aws.protocoltests.json#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11FooErrorWithNestedTypeProperty", + "documentation": "Some services serialize errors using __type, and if the response includes additional shapes that belong to a different namespace there'll be a nested __type property that must not be considered when determining which error to be surfaced.\n\nFor an example service see Amazon DynamoDB.", + "protocol": "aws.protocols#awsJson1_1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "__type": "aws.protocoltests.json#FooError",\n "ErrorDetails": [\n {\n "__type": "com.amazon.internal#ErrorDetails",\n "reason": "Some reason"\n }\n ]\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="server"), + ], +) + +FRACTIONAL_SECONDS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#FractionalSecondsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +FRACTIONAL_SECONDS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#FractionalSecondsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"datetime": {"target": DATE_TIME}}, +) + +FRACTIONAL_SECONDS = Schema( + id=ShapeID("aws.protocoltests.json#FractionalSeconds"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11DateTimeWithFractionalSeconds", + "documentation": "Ensures that clients can correctly parse datetime timestamps with fractional seconds", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": ' {\n "datetime": "2000-01-02T20:34:56.123Z"\n }\n', + "params": MappingProxyType({"datetime": 9.46845296123e8}), + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +GREETING_WITH_ERRORS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#GreetingWithErrorsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +GREETING_WITH_ERRORS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#GreetingWithErrorsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"greeting": {"target": STRING}}, +) + +INVALID_GREETING = Schema.collection( + id=ShapeID("aws.protocoltests.json#InvalidGreeting"), + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11InvalidGreetingError", + "documentation": "Parses simple JSON errors", + "protocol": "aws.protocols#awsJson1_1", + "params": MappingProxyType({"Message": "Hi"}), + "code": 400, + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "body": '{\n "__type": "InvalidGreeting",\n "Message": "Hi"\n}', + "bodyMediaType": "application/json", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="client"), + ], + members={"Message": {"target": STRING}}, +) + +GREETING_WITH_ERRORS = Schema( + id=ShapeID("aws.protocoltests.json#GreetingWithErrors"), + shape_type=ShapeType.OPERATION, + traits=[Trait.new(id=ShapeID("smithy.api#idempotent"))], +) + +HOST_WITH_PATH_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#HostWithPathOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +HOST_WITH_PATH_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#HostWithPathOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HOST_WITH_PATH_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json#HostWithPathOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11HostWithPath", + "documentation": "Custom endpoints supplied by users can have paths", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/custom/", + "body": "{}", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.HostWithPathOperation", + } + ), + "host": "example.com/custom", + "appliesTo": "client", + } + ), + ), + ) + ], +) + +FOO_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnum"), + shape_type=ShapeType.ENUM, + members={ + "FOO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Foo")], + }, + "BAZ": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Baz")], + }, + "BAR": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Bar")], + }, + "ONE": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="1")], + }, + "ZERO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="0")], + }, + }, +) + +FOO_ENUM_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnumList"), + shape_type=ShapeType.LIST, + members={"member": {"target": FOO_ENUM}}, +) + +FOO_ENUM_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnumMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": FOO_ENUM}}, +) + +FOO_ENUM_SET = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnumSet"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#uniqueItems"))], + members={"member": {"target": FOO_ENUM}}, +) + +JSON_ENUMS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#JsonEnumsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#JsonEnumsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "fooEnum1": {"target": FOO_ENUM}, + "fooEnum2": {"target": FOO_ENUM}, + "fooEnum3": {"target": FOO_ENUM}, + "fooEnumList": {"target": FOO_ENUM_LIST}, + "fooEnumSet": {"target": FOO_ENUM_SET}, + "fooEnumMap": {"target": FOO_ENUM_MAP}, + }, +) + +JSON_ENUMS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#JsonEnumsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#JsonEnumsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "fooEnum1": {"target": FOO_ENUM}, + "fooEnum2": {"target": FOO_ENUM}, + "fooEnum3": {"target": FOO_ENUM}, + "fooEnumList": {"target": FOO_ENUM_LIST}, + "fooEnumSet": {"target": FOO_ENUM_SET}, + "fooEnumMap": {"target": FOO_ENUM_MAP}, + }, +) + +JSON_ENUMS = Schema( + id=ShapeID("aws.protocoltests.json#JsonEnums"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11Enums", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "fooEnum1": "Foo",\n "fooEnum2": "0",\n "fooEnum3": "1",\n "fooEnumList": [\n "Foo",\n "0"\n ],\n "fooEnumSet": [\n "Foo",\n "0"\n ],\n "fooEnumMap": {\n "hi": "Foo",\n "zero": "0"\n }\n}', + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonEnums", + } + ), + "bodyMediaType": "application/json", + "params": MappingProxyType( + { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": ("Foo", "0"), + "fooEnumSet": ("Foo", "0"), + "fooEnumMap": MappingProxyType( + {"hi": "Foo", "zero": "0"} + ), + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11Enums", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "fooEnum1": "Foo",\n "fooEnum2": "0",\n "fooEnum3": "1",\n "fooEnumList": [\n "Foo",\n "0"\n ],\n "fooEnumSet": [\n "Foo",\n "0"\n ],\n "fooEnumMap": {\n "hi": "Foo",\n "zero": "0"\n }\n}', + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "bodyMediaType": "application/json", + "params": MappingProxyType( + { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": ("Foo", "0"), + "fooEnumSet": ("Foo", "0"), + "fooEnumMap": MappingProxyType( + {"hi": "Foo", "zero": "0"} + ), + } + ), + } + ), + ), + ), + ], +) + +INTEGER_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnum"), + shape_type=ShapeType.INT_ENUM, + traits=[Trait.new(id=ShapeID("smithy.api#box"))], + members={ + "A": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=1)], + }, + "B": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=2)], + }, + "C": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=3)], + }, + }, +) + +INTEGER_ENUM_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnumList"), + shape_type=ShapeType.LIST, + members={"member": {"target": INTEGER_ENUM}}, +) + +INTEGER_ENUM_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnumMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": INTEGER_ENUM}}, +) + +INTEGER_ENUM_SET = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnumSet"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#uniqueItems"))], + members={"member": {"target": INTEGER_ENUM}}, +) + +JSON_INT_ENUMS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#JsonIntEnumsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#JsonIntEnumsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "intEnum1": {"target": INTEGER_ENUM}, + "intEnum2": {"target": INTEGER_ENUM}, + "intEnum3": {"target": INTEGER_ENUM}, + "intEnumList": {"target": INTEGER_ENUM_LIST}, + "intEnumSet": {"target": INTEGER_ENUM_SET}, + "intEnumMap": {"target": INTEGER_ENUM_MAP}, + }, +) + +JSON_INT_ENUMS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#JsonIntEnumsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#JsonIntEnumsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "intEnum1": {"target": INTEGER_ENUM}, + "intEnum2": {"target": INTEGER_ENUM}, + "intEnum3": {"target": INTEGER_ENUM}, + "intEnumList": {"target": INTEGER_ENUM_LIST}, + "intEnumSet": {"target": INTEGER_ENUM_SET}, + "intEnumMap": {"target": INTEGER_ENUM_MAP}, + }, +) + +JSON_INT_ENUMS = Schema( + id=ShapeID("aws.protocoltests.json#JsonIntEnums"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11IntEnums", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "intEnum1": 1,\n "intEnum2": 2,\n "intEnum3": 3,\n "intEnumList": [\n 1,\n 2\n ],\n "intEnumSet": [\n 1,\n 2\n ],\n "intEnumMap": {\n "a": 1,\n "b": 2\n }\n}', + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonIntEnums", + } + ), + "bodyMediaType": "application/json", + "params": MappingProxyType( + { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": (1, 2), + "intEnumSet": (1, 2), + "intEnumMap": MappingProxyType({"a": 1, "b": 2}), + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11IntEnums", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "intEnum1": 1,\n "intEnum2": 2,\n "intEnum3": 3,\n "intEnumList": [\n 1,\n 2\n ],\n "intEnumSet": [\n 1,\n 2\n ],\n "intEnumMap": {\n "a": 1,\n "b": 2\n }\n}', + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonIntEnums", + } + ), + "bodyMediaType": "application/json", + "params": MappingProxyType( + { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": (1, 2), + "intEnumSet": (1, 2), + "intEnumMap": MappingProxyType({"a": 1, "b": 2}), + } + ), + } + ), + ), + ), + ], +) + +STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING}}, +) + +STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +GREETING_STRUCT = Schema.collection( + id=ShapeID("aws.protocoltests.shared#GreetingStruct"), + members={"hi": {"target": STRING}}, +) + +MY_UNION = Schema.collection( + id=ShapeID("aws.protocoltests.json#MyUnion"), + shape_type=ShapeType.UNION, + members={ + "stringValue": {"target": STRING}, + "booleanValue": {"target": BOOLEAN}, + "numberValue": {"target": INTEGER}, + "blobValue": {"target": BLOB}, + "timestampValue": {"target": TIMESTAMP}, + "enumValue": {"target": FOO_ENUM}, + "listValue": {"target": STRING_LIST}, + "mapValue": {"target": STRING_MAP}, + "structureValue": {"target": GREETING_STRUCT}, + }, +) + +JSON_UNIONS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#JsonUnionsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#UnionInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"contents": {"target": MY_UNION}}, +) + +JSON_UNIONS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#JsonUnionsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#UnionInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"contents": {"target": MY_UNION}}, +) + +JSON_UNIONS = Schema( + id=ShapeID("aws.protocoltests.json#JsonUnions"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11SerializeStringUnionValue", + "documentation": "Serializes a string union value", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "stringValue": "foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"stringValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SerializeBooleanUnionValue", + "documentation": "Serializes a boolean union value", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "booleanValue": true\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"booleanValue": True})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SerializeNumberUnionValue", + "documentation": "Serializes a number union value", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "numberValue": 1\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"numberValue": 1})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SerializeBlobUnionValue", + "documentation": "Serializes a blob union value", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "blobValue": "Zm9v"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"blobValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SerializeTimestampUnionValue", + "documentation": "Serializes a timestamp union value", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "timestampValue": 1398796238\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions", + } + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"timestampValue": 1398796238} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SerializeEnumUnionValue", + "documentation": "Serializes an enum union value", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "enumValue": "Foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions", + } + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"enumValue": "Foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SerializeListUnionValue", + "documentation": "Serializes a list union value", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions", + } + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"listValue": ("foo", "bar")} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SerializeMapUnionValue", + "documentation": "Serializes a map union value", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions", + } + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "mapValue": MappingProxyType( + {"foo": "bar", "spam": "eggs"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SerializeStructureUnionValue", + "documentation": "Serializes a structure union value", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.JsonUnions", + } + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11DeserializeStringUnionValue", + "documentation": "Deserializes a string union value", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "stringValue": "foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"stringValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11DeserializeBooleanUnionValue", + "documentation": "Deserializes a boolean union value", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "booleanValue": true\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"booleanValue": True})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11DeserializeNumberUnionValue", + "documentation": "Deserializes a number union value", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "numberValue": 1\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"numberValue": 1})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11DeserializeBlobUnionValue", + "documentation": "Deserializes a blob union value", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "blobValue": "Zm9v"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"blobValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11DeserializeTimestampUnionValue", + "documentation": "Deserializes a timestamp union value", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "timestampValue": 1398796238\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"timestampValue": 1398796238} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11DeserializeEnumUnionValue", + "documentation": "Deserializes an enum union value", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "enumValue": "Foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"enumValue": "Foo"})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11DeserializeListUnionValue", + "documentation": "Deserializes a list union value", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"listValue": ("foo", "bar")} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11DeserializeMapUnionValue", + "documentation": "Deserializes a map union value", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "mapValue": MappingProxyType( + {"foo": "bar", "spam": "eggs"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11DeserializeStructureUnionValue", + "documentation": "Deserializes a structure union value", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11DeserializeIgnoreType", + "appliesTo": "client", + "documentation": "Ignores an unrecognized __type property", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "contents": {\n "__type": "aws.protocoltests.json10#MyUnion",\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + ), + ), + ], +) + +NULL_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#NullOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#NullOperationInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"string": {"target": STRING}}, +) + +NULL_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#NullOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#NullOperationInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"string": {"target": STRING}}, +) + +NULL_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json#NullOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11StructuresDontSerializeNullValues", + "documentation": "Null structure values are dropped", + "protocol": "aws.protocols#awsJson1_1", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.NullOperation", + } + ), + "params": MappingProxyType({"string": None}), + "method": "POST", + "uri": "/", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11ServersDontDeserializeNullStructureValues", + "documentation": "Null structure values are dropped", + "protocol": "aws.protocols#awsJson1_1", + "body": '{\n "string": null\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.NullOperation", + } + ), + "params": MappingProxyType({}), + "method": "POST", + "uri": "/", + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11StructuresDontDeserializeNullValues", + "documentation": "Null structure values are dropped", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "string": null\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsJson11ServersDontSerializeNullStructureValues", + "documentation": "Null structure values are dropped", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"string": None}), + "appliesTo": "server", + } + ), + ), + ), + ], +) + +OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#OperationWithOptionalInputOutputInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"Value": {"target": STRING}}, +) + +OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#OperationWithOptionalInputOutputOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"Value": {"target": STRING}}, +) + +OPERATION_WITH_OPTIONAL_INPUT_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.json#OperationWithOptionalInputOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "can_call_operation_with_no_input_or_output", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Can call operations with no input or output", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.OperationWithOptionalInputOutput", + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "can_call_operation_with_optional_input", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Can invoke operations with optional input", + "body": '{"Value":"Hi"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.OperationWithOptionalInputOutput", + } + ), + "params": MappingProxyType({"Value": "Hi"}), + "method": "POST", + "uri": "/", + } + ), + ), + ) + ], +) + +PUT_AND_GET_INLINE_DOCUMENTS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#PutAndGetInlineDocumentsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#PutAndGetInlineDocumentsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"inlineDocument": {"target": DOCUMENT}}, +) + +PUT_AND_GET_INLINE_DOCUMENTS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#PutAndGetInlineDocumentsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#PutAndGetInlineDocumentsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"inlineDocument": {"target": DOCUMENT}}, +) + +PUT_AND_GET_INLINE_DOCUMENTS = Schema( + id=ShapeID("aws.protocoltests.json#PutAndGetInlineDocuments"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "PutAndGetInlineDocumentsInput", + "documentation": "Serializes inline documents in a JSON request.", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "inlineDocument": {"foo": "bar"}\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.PutAndGetInlineDocuments", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"inlineDocument": MappingProxyType({"foo": "bar"})} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "PutAndGetInlineDocumentsInput", + "documentation": "Serializes inline documents in a JSON response.", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "inlineDocument": {"foo": "bar"}\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"inlineDocument": MappingProxyType({"foo": "bar"})} + ), + } + ), + ), + ), + ], +) + +PUT_WITH_CONTENT_ENCODING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#PutWithContentEncodingInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "encoding": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="Content-Encoding") + ], + }, + "data": {"target": STRING}, + }, +) + +PUT_WITH_CONTENT_ENCODING_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#PutWithContentEncodingOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +PUT_WITH_CONTENT_ENCODING = Schema( + id=ShapeID("aws.protocoltests.json#PutWithContentEncoding"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "SDKAppliedContentEncoding_awsJson1_1", + "documentation": "Compression algorithm encoding is appended to the Content-Encoding header.", + "protocol": "aws.protocols#awsJson1_1", + "params": MappingProxyType( + { + "data": "RjCEL3kBwqPivZUXGiyA5JCujtWgJAkKRlnTEsNYfBRGOS0f7LT6R3bCSOXeJ4auSHzQ4BEZZTklUyj5\n1HEojihShQC2jkQJrNdGOZNSW49yRO0XbnGmeczUHbZqZRelLFKW4xjru9uTuB8lFCtwoGgciFsgqTF8\n5HYcoqINTRxuAwGuRUMoNO473QT0BtCQoKUkAyVaypG0hBZdGNoJhunBfW0d3HWTYlzz9pXElyZhq3C1\n2PDB17GEoOYXmTxDecysmPOdo5z6T0HFhujfeJFIQQ8dirmXcG4F3v0bZdf6AZ3jsiVh6RnEXIPxPbOi\ngIXDWTMUr4Pg3f2LdYCM01eAb2qTdgsEN0MUDhEIfn68I2tnWvcozyUFpg1ez6pyWP8ssWVfFrckREIM\nMb0cTUVqSVSM8bnFiF9SoXM6ZoGMKfX1mT708OYk7SqZ1JlCTkecDJDoR5ED2q2MWKUGR6jjnEV0GtD8\nWJO6AcF0DptY9Hk16Bav3z6c5FeBvrGDrxTFVgRUk8SychzjrcqJ4qskwN8rL3zslC0oqobQRnLFOvwJ\nprSzBIwdH2yAuxokXAdVRa1u9NGNRvfWJfKkwbbVz8yV76RUF9KNhAUmwyYDrLnxNj8ROl8B7dv8Gans\n7Bit52wcdiJyjBW1pAodB7zqqVwtBx5RaSpF7kEMXexYXp9N0J1jlXzdeg5Wgg4pO7TJNr2joiPVAiFf\nefwMMCNBkYx2z7cRxVxCJZMXXzxSKMGgdTN24bJ5UgE0TxyV52RC0wGWG49S1x5jGrvmxKCIgYPs0w3Z\n0I3XcdB0WEj4x4xRztB9Cx2Mc4qFYQdzS9kOioAgNBti1rBySZ8lFZM2zqxvBsJTTJsmcKPr1crqiXjM\noVWdM4ObOO6QA7Pu4c1hT68CrTmbcecjFcxHkgsqdixnFtN6keMGL9Z2YMjZOjYYzbUEwLJqUVWalkIB\nBkgBRqZpzxx5nB5t0qDH35KjsfKM5cinQaFoRq9y9Z82xdCoKZOsUbxZkk1kVmy1jPDCBhkhixkc5PKS\nFoSKTbeK7kuCEZCtR9OfF2k2MqbygGFsFu2sgb1Zn2YdDbaRwRGeaLhswta09UNSMUo8aTixgoYVHxwy\nvraLB6olPSPegeLOnmBeWyKmEfPdbpdGm4ev4vA2AUFuLIeFz0LkCSN0NgQMrr8ALEm1UNpJLReg1ZAX\nzZh7gtQTZUaBVdMJokaJpLk6FPxSA6zkwB5TegSqhrFIsmvpY3VNWmTUq7H0iADdh3dRQ8Is97bTsbwu\nvAEOjh4FQ9wPSFzEtcSJeYQft5GfWYPisDImjjvHVFshFFkNy2nN18pJmhVPoJc456tgbdfEIdGhIADC\n6UPcSSzE1FxlPpILqZrp3i4NvvKoiOa4a8tnALd2XRHHmsvALn2Wmfu07b86gZlu4yOyuUFNoWI6tFvd\nbHnqSJYNQlFESv13gJw609DBzNnrIgBGYBAcDRrIGAnflRKwVDUnDFrUQmE8xNG6jRlyb1p2Y2RrfBtG\ncKqhuGNiT2DfxpY89ektZ98waPhJrFEPJToNH8EADzBorh3T0h4YP1IeLmaI7SOxeuVrk1kjRqMK0rUB\nlUJgJNtCE35jCyoHMwPQlyi78ZaVv8COVQ24zcGpw0MTy6JUsDzAC3jLNY6xCb40SZV9XzG7nWvXA5Ej\nYC1gTXxF4AtFexIdDZ4RJbtYMyXt8LsEJerwwpkfqvDwsiFuqYC6vIn9RoZO5kI0F35XtUITDQYKZ4eq\nWBV0itxTyyR5Rp6g30pZEmEqOusDaIh96CEmHpOBYAQZ7u1QTfzRdysIGMpzbx5gj9Dxm2PO1glWzY7P\nlVqQiBlXSGDOkBkrB6SkiAxknt9zsPdTTsf3r3nid4hdiPrZmGWNgjOO1khSxZSzBdltrCESNnQmlnP5\nZOHA0eSYXwy8j4od5ZmjA3IpFOEPW2MutMbxIbJpg5dIx2x7WxespftenRLgl3CxcpPDcnb9w8LCHBg7\nSEjrEer6Y8wVLFWsQiv6nTdCPZz9cGqwgtCaiHRy8lTWFgdfWd397vw9rduGld3uUFeFRGjYrphqEmHi\nhiG0GhE6wRFVUsGJtvOCYkVREvbEdxPFeJvlAvOcs9HKbtptlTusvYB86vR2bNcIY4f5JZu2X6sGa354\n7LRk0ps2zqYjat3hMR7XDC8KiKceBteFsXoDjfVxTYKelpedTxqWAafrKhaoAVuNM98PSnkuIWGzjSUC\nNsDJTt6vt1D1afBVPWVmnQ7ZQdtEtLIEwAWYjemAztreELIr1E9fPEILm1Ke4KctP9I0I72Dh4eylNZD\n0DEr2Hg7cWFckuZ0Av5d0IPRARXikEGDHl8uh12TXL9v2Uh0ZVSJMEYvxGSbZvkWz8TjWSk3hKA2a7GL\nJm3Ho7e1C34gE1XRGcEthxvURxt4OKBqN3ZNaMIuDTWinoQAutMcUqtm4MoL7RGPiCHUrvTwQPSirsmA\nQmOEu8nOpnP77Fivh9jLGx5ta7nL6jrsWUsBqiN1lzpdPYLRR4mUIAj6sNWiDEk4pkbHSMEcqbWw6Zl7\npsEyPDHalCNhWMA3RSK3skURzQDZ0oBV5W7vjVIZ4d3uCKsk6zrzEI9u5mx7p9RdNKodXfzqYt0ULdtc\n3RW0hIfw2KvrO3BD2QrtgAkfrFBGVvlJSUoh0MvLz8DeXxfuiuq9Ttu7wvsqVI4Piah6WNEXtHHGPJO3\nGhc75Bnv2To4VS2v8rmyKAPIIVTuYBHZN6sZ4FhFzbrslCIdk0eadaU60naqiNWU3CsxplIYGyeThmJ7\n9u4h6Y2OmiPZjFPS2bAzwgAozYTVefII9aEaWZ0hxHZeu1FW7r79dkdO73ZqRfas9u8Z7LLBPCw5pV0F\n5I0pHDgNb6MogoxF4NZJfVtIX1vCHhhVLrXjrYNJU2fD9Fw8kT8Ie2HDBJnqAvYKmryQ1r9ulo3Me3rH\nq9s2Y5uCDxu9iQNhnpwIm57WYGFeqd2fnQeY2IziD3Jgx0KSrmOH0jgi0RwJyfGXaORPq3bQQqljuACo\nkO6io9t5VI8PbNxSHTRbtYiPciUslbT0g7SpCLrRPOBRJ4DDk56pjghpeoUagJ5xJ4wjBzBuXnAGkNnP\nTfpiuz2r3oSBAi8sB9wiYK2z9sp4gZyQsqdVNzAEgKatOxBRBmJCBYpjO98ZQrF83XApPpfFg0ujB2PW\n1iYF9NkgwIKB5oB6KVTOmSKJk11mVermPgeugHbzdd2zUP6fP8fWbhseqk2t8ahGvqjs2CDHFIWXl5jc\nfCknbykE3ANt7lnAfJQ2ddduLGiqrX4HWx6jcWw08Es6BkleO0IDbaWrb95d5isvFlzJsf0TyDIXF4uq\nbBDCi0XPWqtRJ2iqmnJa2GbBe9GmAOWMkBFSilMyC4sR395WSDpD56fx0NGoU6cHrRu9xF2Bgh7RGSfl\nch2GXEeE02fDpSHFNvJBlOEqqfkIX6oCa6KY9NThqeIjYsT184XR2ZI7akXRaw1gMOGpk4FmUxk6WIuX\n4ei1SLQgSdl7OEdRtJklZ76eFrMbkJQ2TDhu8f7mVuiy53GUMIvCrP9xYGZGmCIDm2e4U2BDi3F7C5xK\n3bDZXwlQp6z4BSqTy2OVEWxXUJfjPMOL5Mc7AvDeKtxAS73pVIv0HgHIa4NBAdC7uLG0zXuu1FF6z2XY\nyUhk03fMZhYe7vVxsul3WE7U01fuN8z2y0eKwBW1RFBE1eKIaR9Y01sIWQWbSrfHfDrdZiElhmhHehfs\n0EfrR4sLYdQshJuvhTeKGJDaEhtPQwwJ9mUYGtuCL9RozWx1XI4bHNlzBTW0BVokYiJGlPe7wdxNzJD7\nJgS7Lwv6jGKngVf86imGZyzqwiteWFPdNUoWdTvUPSMO5xIUK9mo5QpwbBOAmyYzVq42o3Qs90N9khEV\nU36LB99fw8PtGHH5wsCHshfauwnNPj0blGXzke0kQ4JNCVH7Jtn0Y0aeejkSxFtwtxoYs6zHl1Lxxpsd\nsw5vBy49CEtoltDW367lVAwDjWdx20msGB7qJCkEDrzu7EXSO22782QX9NBRcN9ppX0C25I0FMA4Wnhz\n9zIpiXRrsTH35jzM8Cjt4EVLGNU3O0HuEvAer3cENnMJtngdrT86ox3fihMQbiuy4Bh4DEcP5in2VjbT\n3qbnoCNvOi8Fmmf7KlGlWAOceL5OHVE5lljjQEMzEQOCEgrk5mDKgwSBJQBNauIDSC1a5iEQjB8Xxp4C\nqeKyyWY9IOntNrtU5ny4lNprHJd36dKFeBLKcGCOvgHBXdOZloMF0YTRExw7hreEO9IoTGVHJ4teWsNr\nHdtagUHjkeZkdMMfnUGNv5aBNtFMqhcZH6EitEa9lGPkKBbJpoom3u8D8EHSIF1H5EZqqx9TLY5hWAIG\nPwJ4qwkpCGw5rCLVrjw7ARKukIFzNULANqjHUMcJ002TlUosJM4xJ4aAgckpLVGOGuPDhGAAexEcQmbg\nUsZdmqQrtuVUyyLteLbLbqtR6CTlcAIwY3xyMCmPgyefE0FEUODBoxQtRUuYTL9RC5o1sYb2PvcxUQfb\niJFi2CAl99pAzcckU2qVCxniARslIxM5pmMRGsQX9ZzYAfZrbg6ce6S74I8UMlgRQ2QVyvUjKKOE6IrJ\nLng370emHfe5m6LZULD5YiZutkD5ipjL2Bz77DvTE5kNPUhuoKBcTJcUgytfXAKUTWOcRKNlq0GImrxM\nJfr7AWbLFFNKGLeTrVDBwpcokJCv0zcOKWe8fd2xkeXkZTdmM66IgM27cyYmtQ6YF26Kd0qrWJeVZJV9\n3fyLYYvKN5csbRY2BHoYE5ERARRW65IrpkXMf48OrCXMtDIP0Z7wxI9DiTeKKeH4uuguhCJnwzR3WxLA\nVU6eBJEd7ZjS6JA83w7decq8uDI7LGKjcz1FySp3B7fE9DkHRGXxbsL7Fjar6vW2mAv8CuvI20B6jctp\n2yLDs24sPfB3sSxrrlhbuT1m6DZqiN0dl6umKx7NGZhmOTVGr20jfcxhqPQwTJfd7kel4rvxip4BqkvT\n7STy8knJ2BXGyJeNgwo1PXUZRDVy0LCTsSF1RFuRZe8cktHl9lgw8ntdPn1pVFL0MwJkJfdXBNUp5gNv\n50FTkrpo1t6wq4CVbcfj2XOrOzvBUzNH26sXGABI1gGxCdp2jEZrHgqQaWIaTJVTuguZhxqDvdYsrwFW\nYN58uuNcKHIrGdRSigyZInwQDYk0pjcqdSeU0WVU3Y9htzZBR7XRaCJr5YTZvq7fwermb5tuwb37lPLq\nB2IGg0iftkVbXaSyfCwVaRbfLBb88so0QqpmJGirFu8FcDiXOV1zTr8yW9XLdYQuUjh43xrXLdgsuYff\nCagInUk1eU1aLjVZoJRsNmStmOEpAqlYMwTvx7w6j2f421Cxr5cNZBIVlAxlXN2QiDqJ9v3sHhHkTanc\nlQuH8ptUyX8qncpBuXXBn7cSez9N0EoxCBl1GHUagbjstgJo4gzLvTmVIY6MiWYOBitzNUHfyqKwtKUr\nVoSCdZcGeA9lHUPA7PUprRRaT3m1hGKPyshtVS2ikG48w3oVerln1N1qGdtz46gZCrndw3LZ1B362RfW\nzDPuXbpsyLsRMTt1Rz1oKHRXp3iE41hkhQH6pxlvyCW2INnHt5XU8zRamOB3oW0udOhMpQFDjRkOcy06\nb4t0QTHvoRqmBna3WXzIMZyeK3GChF5eF8oDXRbjhk7BB6YKCgqwWUzEJ5K47HMSlhFkBUjaPRjdGM0z\nzOMwhW6b1NvSwP7XM1P5yi1oPvOspts1vr29SXqrMMrBhVogeodWyd69NqrO4jkyBxKmlXifoTowpfiY\n2cUCE0XMZqxUN39LCP09JqZifaEcBEo3mgtm1tWu5QR2GNq7UyQf4RIPSDOpDCAtwoPhRgdT1lJdcj4U\nlnH0wrJ8Uwu7c08L7ErnIrDATqCrOjpSbzGP1xHENABYONC4TknFPrJ8pe40A8fzGT0qBw9mAM1SKcHO\nfoiLcMC9AjHTqJzDG3xplSLPG9or2rMeq7Fzp9r0y7uJRMxgg51EbjfvYlH466A3ggvL2WQlDXjJqPW3\nBJGWAWDNN9LK8f46bADKPxakpkx23S9O47rGSXfDhVSIZsDympxWX1UOzWwMZRHkofVeKqizgbKkGgUT\nWykE9gRoRAOd9wfHZDYKa9i0LaPDiaUMvnU1gdBIqIoiVsdJ9swX47oxvMtOxtcS0zlD6llDkBuIiU5g\nPwRCYmtkkb25c8iRJXwGFPjI1wJ34I1z1ENicPdosPiUe9ZC2jnXIKzEdv01x2ER7DNDF3yxOwOhxNxI\nGqsmC92j25UQQFu9ZstOZ28AoCkuOYs0Uycm5u8jR1T39dMBwrko09rC65ENLnsxM8oebmyFCPiGJ1ED\n5Xqc9qZ237f1OnETAoEOwqUSvrdPTv56U7hV91EMTyC812MLQpr2710E3VVpsUCUMNhIxdt7UXZ1UNFb\njgzpZLXnf4DHrv6B7kq6UI50KMxcw1HZE2GpODfUTzNFLaqdrvzxKe5eUWdcojBaRbD4fFdVYJTElYDH\nNNVh6ofkoeWcs9CWGFmSBe0T4K8phFeygQg0prKMELNEy6qENzVtG9ZDcqj3a7L6ZLtvq50anWp7fAVu\nfwz55g4iM2Z2fA0pnwHDL7tt67zTxGITvsnJsZSpeq1EQsZcwtkBV9liu7Rl7jiVT1IIRtchB8TsTiaA\nwVHIQQ9RIOTiPQdKNqi1kC9iGlUqWK93gblNWlBw1eYB9Wk8FQogutwTf0caNMx8D4nPbANcmOOlskIy\nzALh15OlTrWnhP95rf08AN2J026zDE2DUF9k0eCevYBQIDjqKNW4XCZnjbHoIcKzbY5VzPbMs3ZyMz8K\nSucBmgPg6wrSK5ykbkapS5vuqvXc9GbjQJ8bPNzoxoWGyjbZvDs2OBrIqBmcQb2DLJ8v38McQ4mC4UsS\njf4PyfSCtpk274QZjvLCZbLiCBxQegk7jUU0NmTFJAcYCxd9xMWdlFkiszcltT2YzwuFFz7iA6aa4n5L\nHpBNfUA01GcAi1aCMYhmooS4zSlYcSOZkovMz36U3Fd9WtqIEOJLi7HMgHQDgNMdK6DTzAdHQtxerxVF\nHJnPrfNVG7270r3bp0bPnLNYLhObbAn6zqSAUeLtI2Y4KJDjBKCAh2vvYGbu0e2REYJWRj7MkGevsSSy\nb1kCXLt6tKGWAb7lt5c0xyJgUIJW7pdtnwgT0ZCa24BecCAwNnG5U2EwQbcjZGsFxqNGfaemd3oFEhES\nBaE0Fxms9UKTnMafu8wvZ2xymMrUduuRzOjDeX7oD5YsLC88V8CGMLxbbxIpt94KGykbr6e7L0R4oZl1\ntKMgFwQ2p9Txdbp0Y293LcsJymKizqI0F2xEp7y4SmWOJqHZtsbz80wVV9nv41CvtfxuSoGZJ5cNB7pI\nBgzNcQCeH3Jt0RaGGwboxxpuFbzilmkMFXxJm87tD4WNgu01nHfGCKeQcySEBZpVfJgi6sDFJ8uWnvKm\n9mPLHurtWzEfKqUEa1iC71bXjw5wrvhv9BYW8JSUELHmDquftQyKdq0DZXhULMHGQLf4e95WIaoA14LL\nbThz77kuhKULPTu2MNrBUKGorurhGugo5gs4ZUezSsUOe3KxYdrFMdGgny1GgTxMSMTp2RAZytKjv4kQ\nVx7XgzvpQLIbDjUPAkJv6lScwIRq1W3Ne0Rh0V6Bmn6U5uIuWnJjULmbaQiSODj3z0mAZvak0mSWIGwT\nTX83HztcC4W7e1f6a1thmcc5K61Icehla2hBELWPpixTkyC4eEVmk9Rq0m0ZXtx0JX2ZQXqXDEyePyMe\nJ70sdSzXk72zusqhY4yuOMGgbYNHqxOToK6NxujR7e4dV3Wk5JnSUthym8scjcPeCiKDNY4cHfTMnDXJ\n9zLVy01LtNKYpJ1s8FxVxigmxQNKEbIamxhx6yqwGC4aiISVOOUEjvNOdaUfXfUsE6jEwtwxyGxjlRK1\ncLyxXttq4QWN6PehgHv7jXykzPjInbEysebFvvPOOMdunmJvcCNMSvjUda8fL6xfGo0FDrLg8XZipd6S\noPVdYtyIM1Dg40KbBA3JuumPYtXuJaHrZnjZmdnM5OVo4ZNxktfCVT0c6bnD4bAeyn4bYt1ZPaX6hQHh\nJtvNYfpD0ONYlmqKuToQAMlz52Fh6bj45EbX89L5eLlSpWeyBlGotzriB0EPlclrGi5l2B5oPb1aB1ag\nyyYuu44l0F1oOVYnBIZsxIsHVITxi9lEuVPFkWASOUNuVQXfM4n5hxWR9qtuKnIcPsvbJsv1U10XlKh3\nKisqPhHU15xrCLr5gwFxPUKiNTLUBrkzgBOHXPVsHcLCiSD0YU56TRGfvEom43TWUKPPfl9Z54tgVQuT\njCRlaljAzeniQIcbbHZnn3f0HxbDG3DFYqWSxNrXabHhRsIOhhUHSPENyhGSTVO5t0XX5CdMspJPCd02\n3Oqv32ccbUK4O3YH6LEvp0WO3kSl5n50odVkI9B0i0iq4UPFGMkM8bEQJbgJoOH71P10vtdevJFQE4g2\nyhimiM53ZJRWgSZveHtENZc0Gjo0F9eioak9BnPpY1QxAFPC817svuhEstcU69bLCA4D1rO5R8AuIIBq\nyQJcifFLvbpAEYTLKJqysZrU8EEl3TSdC13A9hZvk4NC8VGEDAxcNrKw313dZp17kZPO5HSd1y6sljAW\nA9M1d6FMYV5SlBWf3WZNCUPS7qKNlda2YBsC6IUVB363f5RLGQOQHwbaijBSRCkrVoRxBHtc0Bd5J9V9\nP5uMTXkpZOxRcCQvImGgcmGuxxLb5zTqfS2xu7v3Sf3IIesSt9tVzcEcdbEvLGVJkLk4mb3G30DbIbri\nPZ09JkweDvMaQ3bxT2nfkz3Ilihkw9jqikkCCCz7E8h6z6KbhQErEW9VzJZzMCgJsyPjFam6iNwpe07S\nhyOvNVw2t9wpzL5xM11DvVzQwDaWEytNRHzDBs4KwEtpI2IpjUyVZHSwA0UGqqkzoCgrJFlNOvPlXqcS\nIcREouUIBmuttkrhPWJtSxOOgpsdvBR3kTOzAXNzSKxoaBAb0c5SDMUc6FIyGA8x5wg5DkUgjFUUodEt\nOYaB2VHVePW9mxHeBTdKWLzJow4ZZvjnoBuVigXljKCNh137ckV2y3Yg3Xi4UzJEI2V5Rw9AfnMs7xUw\nVHOFCg189maD3bmZAe7b4eaGZhyy4HVKjqCXmIH7vsEjRvbnfB0SQxxpuqBDJbHNCtW4vM643ZQQBVPP\na7oXSQIq9w2dHp0A7dtkocCZdQp9FKR9XdJAFIbVSHzIF1ZogeZlc0pXuNE0tagvD57xwDRFkAuoQyMu\nYDdZasXrpSmEE5UjHVkyYsISn8QsfXurzDybX468aoRoks654jjmRY5zi1oB8TcMdC2c3sicNaqfeuhd\nH1nPX7l4RpdqWMR7gGx9slXtG8S3KxpOi4qCD7yg3saD66nun4dzksQURoTUdXyrJR5UpHsfIlTF1aJa\nMdXyQtQnrkl00TeghQd00rRFZsCnhi0qrCSKiBfB2EVrd9RPpbgwJGZHuIQecdBmNetc2ylSEClqVBPR\nGOPPIxrnswEZjmnS0jxKW9VSM1QVxSPJnPFswCqT95SoKD6CP4xdX28WIUGiNaIKodXXJHEIsXBCxLsr\nPwWPCtoplC6hhpKmW5dQo92iCTyY2KioKzO8XR6FKm6qonMKVEwQNtlYE9c97KMtEnp25VOdMP46SQXS\nYsSVp7vm8LP87VYI8SOKcW3s2oedYFtt45rvDzoTF0GmS6wELQ9uo98HhjQAI1Dt91cgjJOwygNmLoZE\nX5K2zQiNA163uMCl5xzaBqY4YTL0wgALg3IFdYSp0RFYLWdt6IxoGI1tnoxcjlUEPo5eGIc3mS3SmaLn\nOdumfUQQ4Jgmgaa5anUVQsfBDrlAN5oaX7O0JO71SSPSWiHBsT9WIPy2J1Cace9ZZLRxblFPSXcvsuHh\nhvnhWQltEDAe7MgvkFQ8lGVFa8jhzijoF9kLmMhMILSzYnfXnZPNP7TlAAwlLHK1RqlpHskJqb6CPpGP\nQvOAhEMsM3zJ2KejZx0esxkjxA0ZufVvGAMN3vTUMplQaF4RiQkp9fzBXf3CMk01dWjOMMIEXTeKzIQe\nEcffzjixWU9FpAyGp2rVl4ETRgqljOGw4UgK31r0ZIEGnH0xGz1FtbW1OcQM008JVujRqulCucEMmntr\n" + } + ), + "method": "POST", + "uri": "/", + "headers": MappingProxyType({"Content-Encoding": "gzip"}), + } + ), + MappingProxyType( + { + "id": "SDKAppendsGzipAndIgnoresHttpProvidedEncoding_awsJson1_1", + "documentation": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is NOT in the Content-Encoding header since HTTP binding\ntraits are ignored in the awsJson1_1 protocol.\n", + "protocol": "aws.protocols#awsJson1_1", + "params": MappingProxyType( + { + "encoding": "custom", + "data": "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\n", + } + ), + "method": "POST", + "uri": "/", + "headers": MappingProxyType({"Content-Encoding": "gzip"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#requestCompression"), + value=MappingProxyType({"encodings": ("gzip",)}), + ), + ], +) + +SIMPLE_SCALAR_PROPERTIES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#SimpleScalarPropertiesInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#SimpleScalarPropertiesInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"floatValue": {"target": FLOAT}, "doubleValue": {"target": DOUBLE}}, +) + +SIMPLE_SCALAR_PROPERTIES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#SimpleScalarPropertiesOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#SimpleScalarPropertiesInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"floatValue": {"target": FLOAT}, "doubleValue": {"target": DOUBLE}}, +) + +SIMPLE_SCALAR_PROPERTIES = Schema( + id=ShapeID("aws.protocoltests.json#SimpleScalarProperties"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11SupportsNaNFloatInputs", + "documentation": "Supports handling NaN float values.", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "floatValue": "NaN",\n "doubleValue": "NaN"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.SimpleScalarProperties", + } + ), + "params": MappingProxyType( + {"floatValue": "NaN", "doubleValue": "NaN"} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SupportsInfinityFloatInputs", + "documentation": "Supports handling Infinity float values.", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "floatValue": "Infinity",\n "doubleValue": "Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.SimpleScalarProperties", + } + ), + "params": MappingProxyType( + {"floatValue": "Infinity", "doubleValue": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SupportsNegativeInfinityFloatInputs", + "documentation": "Supports handling -Infinity float values.", + "protocol": "aws.protocols#awsJson1_1", + "method": "POST", + "uri": "/", + "body": '{\n "floatValue": "-Infinity",\n "doubleValue": "-Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.SimpleScalarProperties", + } + ), + "params": MappingProxyType( + {"floatValue": "-Infinity", "doubleValue": "-Infinity"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11SupportsNaNFloatInputs", + "documentation": "Supports handling NaN float values.", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "floatValue": "NaN",\n "doubleValue": "NaN"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"floatValue": "NaN", "doubleValue": "NaN"} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SupportsInfinityFloatInputs", + "documentation": "Supports handling Infinity float values.", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "floatValue": "Infinity",\n "doubleValue": "Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"floatValue": "Infinity", "doubleValue": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SupportsNegativeInfinityFloatInputs", + "documentation": "Supports handling -Infinity float values.", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "floatValue": "-Infinity",\n "doubleValue": "-Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"floatValue": "-Infinity", "doubleValue": "-Infinity"} + ), + } + ), + ), + ), + ], +) + +SPARSE_STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#SparseStringList"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#sparse"))], + members={"member": {"target": STRING}}, +) + +SPARSE_STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#SparseStringMap"), + shape_type=ShapeType.MAP, + traits=[Trait.new(id=ShapeID("smithy.api#sparse"))], + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +SPARSE_NULLS_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#SparseNullsOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#SparseNullsOperationInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "sparseStringList": {"target": SPARSE_STRING_LIST}, + "sparseStringMap": {"target": SPARSE_STRING_MAP}, + }, +) + +SPARSE_NULLS_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#SparseNullsOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#SparseNullsOperationInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "sparseStringList": {"target": SPARSE_STRING_LIST}, + "sparseStringMap": {"target": SPARSE_STRING_MAP}, + }, +) + +SPARSE_NULLS_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json#SparseNullsOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11SparseMapsSerializeNullValues", + "documentation": "Serializes null values in maps", + "protocol": "aws.protocols#awsJson1_1", + "body": '{\n "sparseStringMap": {\n "foo": null\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.SparseNullsOperation", + } + ), + "params": MappingProxyType( + {"sparseStringMap": MappingProxyType({"foo": None})} + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "AwsJson11SparseListsSerializeNull", + "documentation": "Serializes null values in lists", + "protocol": "aws.protocols#awsJson1_1", + "body": '{\n "sparseStringList": [\n null\n ]\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.SparseNullsOperation", + } + ), + "params": MappingProxyType({"sparseStringList": (None,)}), + "method": "POST", + "uri": "/", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsJson11SparseMapsDeserializeNullValues", + "documentation": "Deserializes null values in maps", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "sparseStringMap": {\n "foo": null\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"sparseStringMap": MappingProxyType({"foo": None})} + ), + } + ), + MappingProxyType( + { + "id": "AwsJson11SparseListsDeserializeNull", + "documentation": "Deserializes null values in lists", + "protocol": "aws.protocols#awsJson1_1", + "code": 200, + "body": '{\n "sparseStringList": [\n null\n ]\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"sparseStringList": (None,)}), + } + ), + ), + ), + ], +) + +KITCHEN_SINK = Schema.collection( + id=ShapeID("aws.protocoltests.json#KitchenSink"), + members={ + "Blob": {"target": BLOB}, + "Boolean": {"target": BOOLEAN}, + "Double": {"target": DOUBLE}, + "EmptyStruct": {"target": EMPTY_STRUCT}, + "Float": {"target": FLOAT}, + "HttpdateTimestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date") + ], + }, + "Integer": {"target": INTEGER}, + "Iso8601Timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time") + ], + }, + "JsonValue": {"target": JSON_VALUE}, + "ListOfLists": {"target": LIST_OF_LIST_OF_STRINGS}, + "ListOfMapsOfStrings": {"target": LIST_OF_MAPS_OF_STRINGS}, + "ListOfStrings": {"target": LIST_OF_STRINGS}, + "ListOfStructs": {"target": LIST_OF_STRUCTS}, + "Long": {"target": LONG}, + "MapOfListsOfStrings": {"target": MAP_OF_LISTS_OF_STRINGS}, + "MapOfMaps": {"target": MAP_OF_MAP_OF_STRINGS}, + "MapOfStrings": {"target": MAP_OF_STRINGS}, + "MapOfStructs": {"target": MAP_OF_STRUCTS}, + # This needs to reference a schema that isn't defined yet. + # It will be populated with a non-null value at the end of the file. + "RecursiveList": None, + # This needs to reference a schema that isn't defined yet. + # It will be populated with a non-null value at the end of the file. + "RecursiveMap": None, + # This needs to reference a schema that isn't defined yet. + # It will be populated with a non-null value at the end of the file. + "RecursiveStruct": None, + "SimpleStruct": {"target": SIMPLE_STRUCT}, + "String": {"target": STRING}, + "StructWithJsonName": {"target": STRUCT_WITH_JSON_NAME}, + "Timestamp": {"target": TIMESTAMP}, + "UnixTimestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ) + ], + }, + }, +) + +LIST_OF_KITCHEN_SINKS = Schema.collection( + id=ShapeID("aws.protocoltests.json#ListOfKitchenSinks"), + shape_type=ShapeType.LIST, + members={"member": {"target": KITCHEN_SINK}}, +) + +MAP_OF_KITCHEN_SINKS = Schema.collection( + id=ShapeID("aws.protocoltests.json#MapOfKitchenSinks"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": KITCHEN_SINK}}, +) + +ERROR_WITH_MEMBERS = Schema.collection( + id=ShapeID("aws.protocoltests.json#ErrorWithMembers"), + traits=[Trait.new(id=ShapeID("smithy.api#error"), value="client")], + members={ + "Code": {"target": STRING}, + "ComplexData": {"target": KITCHEN_SINK}, + "IntegerField": {"target": INTEGER}, + "ListField": {"target": LIST_OF_STRINGS}, + "MapField": {"target": MAP_OF_STRINGS}, + "Message": {"target": STRING}, + "StringField": {"target": STRING}, + }, +) + +KITCHEN_SINK_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#KitchenSinkOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#KitchenSink", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "Blob": {"target": BLOB}, + "Boolean": {"target": BOOLEAN}, + "Double": {"target": DOUBLE}, + "EmptyStruct": {"target": EMPTY_STRUCT}, + "Float": {"target": FLOAT}, + "HttpdateTimestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date") + ], + }, + "Integer": {"target": INTEGER}, + "Iso8601Timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time") + ], + }, + "JsonValue": {"target": JSON_VALUE}, + "ListOfLists": {"target": LIST_OF_LIST_OF_STRINGS}, + "ListOfMapsOfStrings": {"target": LIST_OF_MAPS_OF_STRINGS}, + "ListOfStrings": {"target": LIST_OF_STRINGS}, + "ListOfStructs": {"target": LIST_OF_STRUCTS}, + "Long": {"target": LONG}, + "MapOfListsOfStrings": {"target": MAP_OF_LISTS_OF_STRINGS}, + "MapOfMaps": {"target": MAP_OF_MAP_OF_STRINGS}, + "MapOfStrings": {"target": MAP_OF_STRINGS}, + "MapOfStructs": {"target": MAP_OF_STRUCTS}, + "RecursiveList": {"target": LIST_OF_KITCHEN_SINKS}, + "RecursiveMap": {"target": MAP_OF_KITCHEN_SINKS}, + "RecursiveStruct": {"target": KITCHEN_SINK}, + "SimpleStruct": {"target": SIMPLE_STRUCT}, + "String": {"target": STRING}, + "StructWithJsonName": {"target": STRUCT_WITH_JSON_NAME}, + "Timestamp": {"target": TIMESTAMP}, + "UnixTimestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ) + ], + }, + }, +) + +KITCHEN_SINK_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.json#KitchenSinkOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.json#KitchenSink", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "Blob": {"target": BLOB}, + "Boolean": {"target": BOOLEAN}, + "Double": {"target": DOUBLE}, + "EmptyStruct": {"target": EMPTY_STRUCT}, + "Float": {"target": FLOAT}, + "HttpdateTimestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date") + ], + }, + "Integer": {"target": INTEGER}, + "Iso8601Timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time") + ], + }, + "JsonValue": {"target": JSON_VALUE}, + "ListOfLists": {"target": LIST_OF_LIST_OF_STRINGS}, + "ListOfMapsOfStrings": {"target": LIST_OF_MAPS_OF_STRINGS}, + "ListOfStrings": {"target": LIST_OF_STRINGS}, + "ListOfStructs": {"target": LIST_OF_STRUCTS}, + "Long": {"target": LONG}, + "MapOfListsOfStrings": {"target": MAP_OF_LISTS_OF_STRINGS}, + "MapOfMaps": {"target": MAP_OF_MAP_OF_STRINGS}, + "MapOfStrings": {"target": MAP_OF_STRINGS}, + "MapOfStructs": {"target": MAP_OF_STRUCTS}, + "RecursiveList": {"target": LIST_OF_KITCHEN_SINKS}, + "RecursiveMap": {"target": MAP_OF_KITCHEN_SINKS}, + "RecursiveStruct": {"target": KITCHEN_SINK}, + "SimpleStruct": {"target": SIMPLE_STRUCT}, + "String": {"target": STRING}, + "StructWithJsonName": {"target": STRUCT_WITH_JSON_NAME}, + "Timestamp": {"target": TIMESTAMP}, + "UnixTimestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ) + ], + }, + }, +) + +KITCHEN_SINK_OPERATION = Schema( + id=ShapeID("aws.protocoltests.json#KitchenSinkOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "serializes_string_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes string shapes", + "body": '{"String":"abc xyz"}', + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "bodyMediaType": "application/json", + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"String": "abc xyz"}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_string_shapes_with_jsonvalue_trait", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes string shapes with jsonvalue trait", + "body": '{"JsonValue":"{\\"string\\":\\"value\\",\\"number\\":1234.5,\\"boolTrue\\":true,\\"boolFalse\\":false,\\"array\\":[1,2,3,4],\\"object\\":{\\"key\\":\\"value\\"},\\"null\\":null}"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "JsonValue": '{"string":"value","number":1234.5,"boolTrue":true,"boolFalse":false,"array":[1,2,3,4],"object":{"key":"value"},"null":null}' + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_integer_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes integer shapes", + "body": '{"Integer":1234}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"Integer": 1234}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_long_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes long shapes", + "body": '{"Long":999999999999}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"Long": 999999999999}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_float_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes float shapes", + "body": '{"Float":1234.5}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"Float": 1234.5}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_double_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes double shapes", + "body": '{"Double":1234.5}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"Double": 1234.5}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_blob_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes blob shapes", + "body": '{"Blob":"YmluYXJ5LXZhbHVl"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"Blob": "binary-value"}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_boolean_shapes_true", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes boolean shapes (true)", + "body": '{"Boolean":true}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"Boolean": True}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_boolean_shapes_false", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes boolean shapes (false)", + "body": '{"Boolean":false}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"Boolean": False}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_timestamp_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes timestamp shapes", + "body": '{"Timestamp":946845296}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"Timestamp": 946845296}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_timestamp_shapes_with_iso8601_timestampformat", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes timestamp shapes with iso8601 timestampFormat", + "body": '{"Iso8601Timestamp":"2000-01-02T20:34:56Z"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"Iso8601Timestamp": 946845296}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_timestamp_shapes_with_httpdate_timestampformat", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes timestamp shapes with httpdate timestampFormat", + "body": '{"HttpdateTimestamp":"Sun, 02 Jan 2000 20:34:56 GMT"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"HttpdateTimestamp": 946845296}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_timestamp_shapes_with_unixtimestamp_timestampformat", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes timestamp shapes with unixTimestamp timestampFormat", + "body": '{"UnixTimestamp":946845296}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"UnixTimestamp": 946845296}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_list_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes list shapes", + "body": '{"ListOfStrings":["abc","mno","xyz"]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"ListOfStrings": ("abc", "mno", "xyz")} + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_empty_list_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes empty list shapes", + "body": '{"ListOfStrings":[]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"ListOfStrings": ()}), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_list_of_map_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes list of map shapes", + "body": '{"ListOfMapsOfStrings":[{"foo":"bar"},{"abc":"xyz"},{"red":"blue"}]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "ListOfMapsOfStrings": ( + MappingProxyType({"foo": "bar"}), + MappingProxyType({"abc": "xyz"}), + MappingProxyType({"red": "blue"}), + ) + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_list_of_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes list of structure shapes", + "body": '{"ListOfStructs":[{"Value":"abc"},{"Value":"mno"},{"Value":"xyz"}]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "ListOfStructs": ( + MappingProxyType({"Value": "abc"}), + MappingProxyType({"Value": "mno"}), + MappingProxyType({"Value": "xyz"}), + ) + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_list_of_recursive_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes list of recursive structure shapes", + "body": '{"RecursiveList":[{"RecursiveList":[{"RecursiveList":[{"Integer":123}]}]}]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "RecursiveList": ( + MappingProxyType( + { + "RecursiveList": ( + MappingProxyType( + { + "RecursiveList": ( + MappingProxyType( + {"Integer": 123} + ), + ) + } + ), + ) + } + ), + ) + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_map_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes map shapes", + "body": '{"MapOfStrings":{"abc":"xyz","mno":"hjk"}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "MapOfStrings": MappingProxyType( + {"abc": "xyz", "mno": "hjk"} + ) + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_empty_map_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes empty map shapes", + "body": '{"MapOfStrings":{}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"MapOfStrings": MappingProxyType({})} + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_map_of_list_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes map of list shapes", + "body": '{"MapOfListsOfStrings":{"abc":["abc","xyz"],"mno":["xyz","abc"]}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "MapOfListsOfStrings": MappingProxyType( + {"abc": ("abc", "xyz"), "mno": ("xyz", "abc")} + ) + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_map_of_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes map of structure shapes", + "body": '{"MapOfStructs":{"key1":{"Value":"value-1"},"key2":{"Value":"value-2"}}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "MapOfStructs": MappingProxyType( + { + "key1": MappingProxyType({"Value": "value-1"}), + "key2": MappingProxyType({"Value": "value-2"}), + } + ) + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_map_of_recursive_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes map of recursive structure shapes", + "body": '{"RecursiveMap":{"key1":{"RecursiveMap":{"key2":{"RecursiveMap":{"key3":{"Boolean":false}}}}}}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "RecursiveMap": MappingProxyType( + { + "key1": MappingProxyType( + { + "RecursiveMap": MappingProxyType( + { + "key2": MappingProxyType( + { + "RecursiveMap": MappingProxyType( + { + "key3": MappingProxyType( + { + "Boolean": False + } + ) + } + ) + } + ) + } + ) + } + ) + } + ) + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes structure shapes", + "body": '{"SimpleStruct":{"Value":"abc"}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"SimpleStruct": MappingProxyType({"Value": "abc"})} + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_structure_members_with_locationname_traits", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes structure members with locationName traits", + "body": '{"StructWithJsonName":{"Value":"some-value"}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "StructWithJsonName": MappingProxyType( + {"Value": "some-value"} + ) + } + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_empty_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes empty structure shapes", + "body": '{"SimpleStruct":{}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"SimpleStruct": MappingProxyType({})} + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_structure_which_have_no_members", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes structure which have no members", + "body": '{"EmptyStruct":{}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"EmptyStruct": MappingProxyType({})} + ), + "method": "POST", + "uri": "/", + } + ), + MappingProxyType( + { + "id": "serializes_recursive_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Serializes recursive structure shapes", + "body": '{"String":"top-value","Boolean":false,"RecursiveStruct":{"String":"nested-value","Boolean":true,"RecursiveList":[{"String":"string-only"},{"RecursiveStruct":{"MapOfStrings":{"color":"red","size":"large"}}}]}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/x-amz-json-1.1", + "X-Amz-Target": "JsonProtocol.KitchenSinkOperation", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "String": "top-value", + "Boolean": False, + "RecursiveStruct": MappingProxyType( + { + "String": "nested-value", + "Boolean": True, + "RecursiveList": ( + MappingProxyType({"String": "string-only"}), + MappingProxyType( + { + "RecursiveStruct": MappingProxyType( + { + "MapOfStrings": MappingProxyType( + { + "color": "red", + "size": "large", + } + ) + } + ) + } + ), + ), + } + ), + } + ), + "method": "POST", + "uri": "/", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "parses_operations_with_empty_json_bodies", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses operations with empty JSON bodies", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_string_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses string shapes", + "body": '{"String":"string-value"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"String": "string-value"}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_integer_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses integer shapes", + "body": '{"Integer":1234}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"Integer": 1234}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_long_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses long shapes", + "body": '{"Long":1234567890123456789}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"Long": 1234567890123456789}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_float_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses float shapes", + "body": '{"Float":1234.5}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"Float": 1234.5}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_double_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses double shapes", + "body": '{"Double":123456789.12345679}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"Double": 1.2345678912345679e8}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_boolean_shapes_true", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses boolean shapes (true)", + "body": '{"Boolean":true}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"Boolean": True}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_boolean_false", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses boolean (false)", + "body": '{"Boolean":false}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"Boolean": False}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_blob_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses blob shapes", + "body": '{"Blob":"YmluYXJ5LXZhbHVl"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"Blob": "binary-value"}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_timestamp_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses timestamp shapes", + "body": '{"Timestamp":946845296}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"Timestamp": 946845296}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_iso8601_timestamps", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses iso8601 timestamps", + "body": '{"Iso8601Timestamp":"2000-01-02T20:34:56Z"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"Iso8601Timestamp": 946845296}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_httpdate_timestamps", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses httpdate timestamps", + "body": '{"HttpdateTimestamp":"Sun, 02 Jan 2000 20:34:56 GMT"}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType({"HttpdateTimestamp": 946845296}), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_list_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses list shapes", + "body": '{"ListOfStrings":["abc","mno","xyz"]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + {"ListOfStrings": ("abc", "mno", "xyz")} + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_list_of_map_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses list of map shapes", + "body": '{"ListOfMapsOfStrings":[{"size":"large"},{"color":"red"}]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "ListOfMapsOfStrings": ( + MappingProxyType({"size": "large"}), + MappingProxyType({"color": "red"}), + ) + } + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_list_of_list_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses list of list shapes", + "body": '{"ListOfLists":[["abc","mno","xyz"],["hjk","qrs","tuv"]]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "ListOfLists": ( + ("abc", "mno", "xyz"), + ("hjk", "qrs", "tuv"), + ) + } + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_list_of_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses list of structure shapes", + "body": '{"ListOfStructs":[{"Value":"value-1"},{"Value":"value-2"}]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "ListOfStructs": ( + MappingProxyType({"Value": "value-1"}), + MappingProxyType({"Value": "value-2"}), + ) + } + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_list_of_recursive_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses list of recursive structure shapes", + "body": '{"RecursiveList":[{"RecursiveList":[{"RecursiveList":[{"String":"value"}]}]}]}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "RecursiveList": ( + MappingProxyType( + { + "RecursiveList": ( + MappingProxyType( + { + "RecursiveList": ( + MappingProxyType( + {"String": "value"} + ), + ) + } + ), + ) + } + ), + ) + } + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_map_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses map shapes", + "body": '{"MapOfStrings":{"size":"large","color":"red"}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "MapOfStrings": MappingProxyType( + {"size": "large", "color": "red"} + ) + } + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_map_of_list_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses map of list shapes", + "body": '{"MapOfListsOfStrings":{"sizes":["large","small"],"colors":["red","green"]}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "MapOfListsOfStrings": MappingProxyType( + { + "sizes": ("large", "small"), + "colors": ("red", "green"), + } + ) + } + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_map_of_map_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses map of map shapes", + "body": '{"MapOfMaps":{"sizes":{"large":"L","medium":"M"},"colors":{"red":"R","blue":"B"}}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "MapOfMaps": MappingProxyType( + { + "sizes": MappingProxyType( + {"large": "L", "medium": "M"} + ), + "colors": MappingProxyType( + {"red": "R", "blue": "B"} + ), + } + ) + } + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_map_of_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses map of structure shapes", + "body": '{"MapOfStructs":{"size":{"Value":"small"},"color":{"Value":"red"}}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "MapOfStructs": MappingProxyType( + { + "size": MappingProxyType({"Value": "small"}), + "color": MappingProxyType({"Value": "red"}), + } + ) + } + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_map_of_recursive_structure_shapes", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses map of recursive structure shapes", + "body": '{"RecursiveMap":{"key-1":{"RecursiveMap":{"key-2":{"RecursiveMap":{"key-3":{"String":"value"}}}}}}}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/x-amz-json-1.1"} + ), + "params": MappingProxyType( + { + "RecursiveMap": MappingProxyType( + { + "key-1": MappingProxyType( + { + "RecursiveMap": MappingProxyType( + { + "key-2": MappingProxyType( + { + "RecursiveMap": MappingProxyType( + { + "key-3": MappingProxyType( + { + "String": "value" + } + ) + } + ) + } + ) + } + ) + } + ) + } + ) + } + ), + "code": 200, + } + ), + MappingProxyType( + { + "id": "parses_the_request_id_from_the_response", + "protocol": "aws.protocols#awsJson1_1", + "documentation": "Parses the request id from the response", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "X-Amzn-Requestid": "amazon-uniq-request-id", + "Content-Type": "application/x-amz-json-1.1", + } + ), + "code": 200, + } + ), + ), + ), + ], +) + +JSON_PROTOCOL = Schema( + id=ShapeID("aws.protocoltests.json#JsonProtocol"), + shape_type=ShapeType.SERVICE, + traits=[ + Trait.new( + id=ShapeID("aws.auth#sigv4"), + value=MappingProxyType({"name": "jsonprotocol"}), + ), + Trait.new( + id=ShapeID("smithy.api#title"), value="Sample Json 1.1 Protocol Service" + ), + Trait.new(id=ShapeID("aws.protocols#awsJson1_1")), + Trait.new( + id=ShapeID("aws.api#service"), + value=MappingProxyType( + { + "sdkId": "Json Protocol", + "arnNamespace": "jsonprotocol", + "cloudFormationName": "JsonProtocol", + "cloudTrailEventSource": "jsonprotocol.amazonaws.com", + } + ), + ), + ], +) + +KITCHEN_SINK.members["RecursiveList"] = Schema.member( + id=KITCHEN_SINK.id.with_member("RecursiveList"), + target=LIST_OF_KITCHEN_SINKS, + index=18, +) + +KITCHEN_SINK.members["RecursiveMap"] = Schema.member( + id=KITCHEN_SINK.id.with_member("RecursiveMap"), + target=MAP_OF_KITCHEN_SINKS, + index=19, +) + +KITCHEN_SINK.members["RecursiveStruct"] = Schema.member( + id=KITCHEN_SINK.id.with_member("RecursiveStruct"), target=KITCHEN_SINK, index=20 +) diff --git a/codegen-output/aws-json-1-1/src/awsjson11/auth.py b/codegen-output/aws-json-1-1/src/awsjson11/auth.py new file mode 100644 index 000000000..24ca90fec --- /dev/null +++ b/codegen-output/aws-json-1-1/src/awsjson11/auth.py @@ -0,0 +1,31 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from typing import Any + +from smithy_core.auth import AuthOption as _smithy_core_auth_AuthOption, AuthParams +from smithy_core.interfaces.auth import ( + AuthOption as _smithy_core_interfaces_auth_AuthOption, +) +from smithy_core.shapes import ShapeID + + +class HTTPAuthSchemeResolver: + def resolve_auth_scheme( + self, auth_parameters: AuthParams[Any, Any] + ) -> list[_smithy_core_interfaces_auth_AuthOption]: + auth_options: list[_smithy_core_interfaces_auth_AuthOption] = [] + + if (option := _generate_sigv4_option(auth_parameters)) is not None: + auth_options.append(option) + + return auth_options + + +def _generate_sigv4_option( + auth_params: AuthParams[Any, Any], +) -> _smithy_core_interfaces_auth_AuthOption | None: + return _smithy_core_auth_AuthOption( + scheme_id=ShapeID("aws.auth#sigv4"), + identity_properties={}, # type: ignore + signer_properties={}, # type: ignore + ) diff --git a/codegen-output/aws-json-1-1/src/awsjson11/client.py b/codegen-output/aws-json-1-1/src/awsjson11/client.py new file mode 100644 index 000000000..c32c62ee0 --- /dev/null +++ b/codegen-output/aws-json-1-1/src/awsjson11/client.py @@ -0,0 +1,1381 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +import asyncio +from copy import deepcopy +import logging +from typing import Any, Self, cast + +from smithy_aws_core.config import ConfigSource +from smithy_aws_core.identity import AWSCredentialsIdentity +from smithy_aws_core.identity.chain import IdentityChain +from smithy_core.aio.client import ClientCall, RequestPipeline +from smithy_core.aio.retries import RetryStrategyResolver +from smithy_core.aio.utils import close +from smithy_core.exceptions import ExpectationNotMetError +from smithy_core.interceptors import InterceptorChain +from smithy_core.types import TypedProperties +from smithy_http.aio.interfaces import HTTPClient +from smithy_http.plugins import user_agent_plugin + +from .config import AsyncJsonProtocolConfig, Plugin +from .models import ( + CONTENT_TYPE_PARAMETERS, + ContentTypeParametersInput, + ContentTypeParametersOutput, + DATETIME_OFFSETS, + DatetimeOffsetsInput, + DatetimeOffsetsOutput, + EMPTY_OPERATION, + ENDPOINT_OPERATION, + ENDPOINT_WITH_HOST_LABEL_OPERATION, + EmptyOperationInput, + EmptyOperationOutput, + EndpointOperationInput, + EndpointOperationOutput, + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + FRACTIONAL_SECONDS, + FractionalSecondsInput, + FractionalSecondsOutput, + GREETING_WITH_ERRORS, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HOST_WITH_PATH_OPERATION, + HostWithPathOperationInput, + HostWithPathOperationOutput, + JSON_ENUMS, + JSON_INT_ENUMS, + JSON_UNIONS, + JsonEnumsInput, + JsonEnumsOutput, + JsonIntEnumsInput, + JsonIntEnumsOutput, + JsonUnionsInput, + JsonUnionsOutput, + KITCHEN_SINK_OPERATION, + KitchenSinkOperationInput, + KitchenSinkOperationOutput, + NULL_OPERATION, + NullOperationInput, + NullOperationOutput, + OPERATION_WITH_OPTIONAL_INPUT_OUTPUT, + OperationWithOptionalInputOutputInput, + OperationWithOptionalInputOutputOutput, + PUT_AND_GET_INLINE_DOCUMENTS, + PUT_WITH_CONTENT_ENCODING, + PutAndGetInlineDocumentsInput, + PutAndGetInlineDocumentsOutput, + PutWithContentEncodingInput, + PutWithContentEncodingOutput, + SIMPLE_SCALAR_PROPERTIES, + SPARSE_NULLS_OPERATION, + SimpleScalarPropertiesInput, + SimpleScalarPropertiesOutput, + SparseNullsOperationInput, + SparseNullsOperationOutput, +) +from .user_agent import aws_user_agent_plugin + + +logger = logging.getLogger(__name__) + + +class AsyncJsonProtocolClient: + """Client for JsonProtocol""" + + def __init__( + self, + config: AsyncJsonProtocolConfig | None = None, + plugins: list[Plugin] | None = None, + ): + """ + Constructor for `AsyncJsonProtocolClient`. + + Args: + config: + Optional configuration for the client. Here you can set things like + the endpoint for HTTP services or auth credentials. + plugins: + A list of callables applied once to the client's base configuration. + Their changes are inherited by every operation invocation. + """ + self._config = config + self._plugins = plugins + self._derive_lock = asyncio.Lock() + self._setup_done = False + self._closed = False + self._retry_strategy_resolver = RetryStrategyResolver() + self._client_plugins: list[Plugin] = [aws_user_agent_plugin, user_agent_plugin] + + async def _ensure_setup(self) -> None: + if not self._setup_done: + async with self._derive_lock: + if not self._setup_done: + if self._config is None: + config = await AsyncJsonProtocolConfig.resolve() + else: + # Copy so plugins don't mutate the caller's config. + config = deepcopy(self._config) + for plugin in self._client_plugins: + plugin(config) + if self._plugins: + for plugin in self._plugins: + plugin(config) + self._config = config + + if self._config.aws_credentials_identity_resolver is None: + config_context = self._config.resolution_context() + config_file = None + profile_name = None + if config_context is not None: + config_file = await config_context.parsed_profiles() + if config_context.profile_source is ConfigSource.OVERRIDE: + profile_name = config_context.profile_name + self._config.aws_credentials_identity_resolver = ( + await IdentityChain.create( + AWSCredentialsIdentity, + config_file=config_file, + profile_name=profile_name, + region_override=self._config.region, + http_client=cast( + HTTPClient | None, self._config.transport + ), + ) + ) + self._setup_done = True + + async def close(self) -> None: + """Close this client and any resources held by its transport.""" + if self._closed: + return + async with self._derive_lock: + if self._closed: + return + self._closed = True + if self._setup_done and self._config is not None: + await close(self._config.transport) + + async def __aenter__(self) -> Self: + if self._closed: + raise RuntimeError("Cannot enter a client that has been closed.") + return self + + async def __aexit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: + await self.close() + + async def content_type_parameters( + self, input: ContentTypeParametersInput, plugins: list[Plugin] | None = None + ) -> ContentTypeParametersOutput: + """ + The example tests how servers must support requests containing a + `Content-Type` header with parameters. + + Args: + input: + An instance of `ContentTypeParametersInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `ContentTypeParametersOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=CONTENT_TYPE_PARAMETERS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def datetime_offsets( + self, input: DatetimeOffsetsInput, plugins: list[Plugin] | None = None + ) -> DatetimeOffsetsOutput: + """ + Invokes the DatetimeOffsets operation. + + Args: + input: + An instance of `DatetimeOffsetsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `DatetimeOffsetsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=DATETIME_OFFSETS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def empty_operation( + self, input: EmptyOperationInput, plugins: list[Plugin] | None = None + ) -> EmptyOperationOutput: + """ + Invokes the EmptyOperation operation. + + Args: + input: + An instance of `EmptyOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EmptyOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=EMPTY_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def endpoint_operation( + self, input: EndpointOperationInput, plugins: list[Plugin] | None = None + ) -> EndpointOperationOutput: + """ + Invokes the EndpointOperation operation. + + Args: + input: + An instance of `EndpointOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EndpointOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=ENDPOINT_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def endpoint_with_host_label_operation( + self, + input: EndpointWithHostLabelOperationInput, + plugins: list[Plugin] | None = None, + ) -> EndpointWithHostLabelOperationOutput: + """ + Invokes the EndpointWithHostLabelOperation operation. + + Args: + input: + An instance of `EndpointWithHostLabelOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EndpointWithHostLabelOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=ENDPOINT_WITH_HOST_LABEL_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def fractional_seconds( + self, input: FractionalSecondsInput, plugins: list[Plugin] | None = None + ) -> FractionalSecondsOutput: + """ + Invokes the FractionalSeconds operation. + + Args: + input: + An instance of `FractionalSecondsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `FractionalSecondsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=FRACTIONAL_SECONDS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def greeting_with_errors( + self, input: GreetingWithErrorsInput, plugins: list[Plugin] | None = None + ) -> GreetingWithErrorsOutput: + """ + This operation has three possible return values: 1. A successful + response in the form of GreetingWithErrorsOutput 2. An InvalidGreeting + error. 3. A ComplexError error. Implementations must be able to + successfully take a response and properly deserialize successful and + error responses. + + Args: + input: + An instance of `GreetingWithErrorsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `GreetingWithErrorsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=GREETING_WITH_ERRORS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def host_with_path_operation( + self, input: HostWithPathOperationInput, plugins: list[Plugin] | None = None + ) -> HostWithPathOperationOutput: + """ + Invokes the HostWithPathOperation operation. + + Args: + input: + An instance of `HostWithPathOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HostWithPathOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HOST_WITH_PATH_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_enums( + self, input: JsonEnumsInput, plugins: list[Plugin] | None = None + ) -> JsonEnumsOutput: + """ + This example serializes enums as top level properties, in lists, sets, + and maps. + + Args: + input: + An instance of `JsonEnumsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonEnumsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_ENUMS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_int_enums( + self, input: JsonIntEnumsInput, plugins: list[Plugin] | None = None + ) -> JsonIntEnumsOutput: + """ + This example serializes intEnums as top level properties, in lists, + sets, and maps. + + Args: + input: + An instance of `JsonIntEnumsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonIntEnumsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_INT_ENUMS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_unions( + self, input: JsonUnionsInput, plugins: list[Plugin] | None = None + ) -> JsonUnionsOutput: + """ + This operation uses unions for inputs and outputs. + + Args: + input: + An instance of `JsonUnionsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonUnionsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_UNIONS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def kitchen_sink_operation( + self, input: KitchenSinkOperationInput, plugins: list[Plugin] | None = None + ) -> KitchenSinkOperationOutput: + """ + Invokes the KitchenSinkOperation operation. + + Args: + input: + An instance of `KitchenSinkOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `KitchenSinkOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=KITCHEN_SINK_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def null_operation( + self, input: NullOperationInput, plugins: list[Plugin] | None = None + ) -> NullOperationOutput: + """ + Invokes the NullOperation operation. + + Args: + input: + An instance of `NullOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NullOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NULL_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def operation_with_optional_input_output( + self, + input: OperationWithOptionalInputOutputInput, + plugins: list[Plugin] | None = None, + ) -> OperationWithOptionalInputOutputOutput: + """ + Invokes the OperationWithOptionalInputOutput operation. + + Args: + input: + An instance of `OperationWithOptionalInputOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `OperationWithOptionalInputOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OPERATION_WITH_OPTIONAL_INPUT_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def put_and_get_inline_documents( + self, input: PutAndGetInlineDocumentsInput, plugins: list[Plugin] | None = None + ) -> PutAndGetInlineDocumentsOutput: + """ + This example serializes an inline document as part of the payload. + + Args: + input: + An instance of `PutAndGetInlineDocumentsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `PutAndGetInlineDocumentsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=PUT_AND_GET_INLINE_DOCUMENTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def put_with_content_encoding( + self, input: PutWithContentEncodingInput, plugins: list[Plugin] | None = None + ) -> PutWithContentEncodingOutput: + """ + Invokes the PutWithContentEncoding operation. + + Args: + input: + An instance of `PutWithContentEncodingInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `PutWithContentEncodingOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=PUT_WITH_CONTENT_ENCODING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def simple_scalar_properties( + self, input: SimpleScalarPropertiesInput, plugins: list[Plugin] | None = None + ) -> SimpleScalarPropertiesOutput: + """ + Invokes the SimpleScalarProperties operation. + + Args: + input: + An instance of `SimpleScalarPropertiesInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `SimpleScalarPropertiesOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=SIMPLE_SCALAR_PROPERTIES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def sparse_nulls_operation( + self, input: SparseNullsOperationInput, plugins: list[Plugin] | None = None + ) -> SparseNullsOperationOutput: + """ + Invokes the SparseNullsOperation operation. + + Args: + input: + An instance of `SparseNullsOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `SparseNullsOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=SPARSE_NULLS_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) diff --git a/codegen-output/aws-json-1-1/src/awsjson11/config.py b/codegen-output/aws-json-1-1/src/awsjson11/config.py new file mode 100644 index 000000000..f0dce4d06 --- /dev/null +++ b/codegen-output/aws-json-1-1/src/awsjson11/config.py @@ -0,0 +1,229 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from dataclasses import dataclass, field +from typing import Any, Callable, ClassVar, Self, TypeAlias, Union, Unpack + +from smithy_aws_core.aio.protocols import AwsJson11ClientProtocol +from smithy_aws_core.auth import SigV4AuthScheme +from smithy_aws_core.config import AwsConfigOverrides, FileSystem +from smithy_aws_core.config.aws_config import AsyncAwsConfig +from smithy_aws_core.config.resolvers import EndpointUriResolver +from smithy_aws_core.config.types import FieldSpec +from smithy_aws_core.endpoints.standard_regional import ( + StandardRegionalEndpointsResolver, +) +from smithy_aws_core.identity import AWSCredentialsIdentity, AWSIdentityProperties +from smithy_core.aio.interfaces import ClientProtocol, EndpointResolver +from smithy_core.aio.interfaces.auth import AuthScheme +from smithy_core.aio.interfaces.identity import IdentityResolver +from smithy_core.interceptors import Interceptor +from smithy_core.shapes import ShapeID +from smithy_http.aio.aiohttp import AIOHTTPClient + +from ._private.schemas import JSON_PROTOCOL as _SCHEMA_JSON_PROTOCOL +from .auth import HTTPAuthSchemeResolver +from .models import ( + ContentTypeParametersInput, + ContentTypeParametersOutput, + DatetimeOffsetsInput, + DatetimeOffsetsOutput, + EmptyOperationInput, + EmptyOperationOutput, + EndpointOperationInput, + EndpointOperationOutput, + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + FractionalSecondsInput, + FractionalSecondsOutput, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HostWithPathOperationInput, + HostWithPathOperationOutput, + JsonEnumsInput, + JsonEnumsOutput, + JsonIntEnumsInput, + JsonIntEnumsOutput, + JsonUnionsInput, + JsonUnionsOutput, + KitchenSinkOperationInput, + KitchenSinkOperationOutput, + NullOperationInput, + NullOperationOutput, + OperationWithOptionalInputOutputInput, + OperationWithOptionalInputOutputOutput, + PutAndGetInlineDocumentsInput, + PutAndGetInlineDocumentsOutput, + PutWithContentEncodingInput, + PutWithContentEncodingOutput, + SimpleScalarPropertiesInput, + SimpleScalarPropertiesOutput, + SparseNullsOperationInput, + SparseNullsOperationOutput, +) + + +_ServiceInterceptor = Union[ + Interceptor[ContentTypeParametersInput, ContentTypeParametersOutput, Any, Any], + Interceptor[DatetimeOffsetsInput, DatetimeOffsetsOutput, Any, Any], + Interceptor[EmptyOperationInput, EmptyOperationOutput, Any, Any], + Interceptor[EndpointOperationInput, EndpointOperationOutput, Any, Any], + Interceptor[ + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + Any, + Any, + ], + Interceptor[FractionalSecondsInput, FractionalSecondsOutput, Any, Any], + Interceptor[GreetingWithErrorsInput, GreetingWithErrorsOutput, Any, Any], + Interceptor[HostWithPathOperationInput, HostWithPathOperationOutput, Any, Any], + Interceptor[JsonEnumsInput, JsonEnumsOutput, Any, Any], + Interceptor[JsonIntEnumsInput, JsonIntEnumsOutput, Any, Any], + Interceptor[JsonUnionsInput, JsonUnionsOutput, Any, Any], + Interceptor[KitchenSinkOperationInput, KitchenSinkOperationOutput, Any, Any], + Interceptor[NullOperationInput, NullOperationOutput, Any, Any], + Interceptor[ + OperationWithOptionalInputOutputInput, + OperationWithOptionalInputOutputOutput, + Any, + Any, + ], + Interceptor[ + PutAndGetInlineDocumentsInput, PutAndGetInlineDocumentsOutput, Any, Any + ], + Interceptor[PutWithContentEncodingInput, PutWithContentEncodingOutput, Any, Any], + Interceptor[SimpleScalarPropertiesInput, SimpleScalarPropertiesOutput, Any, Any], + Interceptor[SparseNullsOperationInput, SparseNullsOperationOutput, Any, Any], +] + + +class _AsyncJsonProtocolConfigOverrides(AwsConfigOverrides, total=False): + endpoint_resolver: EndpointResolver | None + protocol: ClientProtocol[Any, Any] | None + auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None + auth_scheme_resolver: HTTPAuthSchemeResolver | None + + +@dataclass(kw_only=True, repr=False, init=False) +class AsyncJsonProtocolConfig(AsyncAwsConfig): + """Json Protocol configuration (async-resolved).""" + + endpoint_resolver: EndpointResolver | None = None + """ + The endpoint resolver used to resolve the final endpoint per-operation + based on the configuration. + """ + + protocol: ClientProtocol[Any, Any] | None = None + """The protocol to serialize and deserialize requests with.""" + + interceptors: list[_ServiceInterceptor] = field(default_factory=lambda: []) + """ + The list of interceptors, which are hooks that are called during the + execution of a request. + """ + + auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None = None + """A map of auth scheme ids to auth schemes.""" + + auth_scheme_resolver: HTTPAuthSchemeResolver | None = None + """ + An auth scheme resolver that determines the auth scheme for each + operation. + """ + + aws_credentials_identity_resolver: ( + IdentityResolver[AWSCredentialsIdentity, AWSIdentityProperties] | None + ) = None + """Resolves AWS Credentials. Required for operations that use Sigv4 Auth.""" + + region: str | None = None + """ + The AWS region to connect to. The configured region is used to determine + the service endpoint. + """ + + aws_access_key_id: str | None = None + """The identifier for a secret access key.""" + + aws_secret_access_key: str | None = None + """A secret access key that can be used to sign requests.""" + + aws_session_token: str | None = None + """The session token used with temporary AWS credentials.""" + + user_agent_extra: str | None = None + """Additional suffix to be added to the User-Agent header.""" + + sdk_ua_app_id: str | None = None + """ + A unique and opaque application ID that is appended to the User-Agent + header. + """ + + _FIELDS: ClassVar[dict[str, FieldSpec]] = { + "aws_credentials_identity_resolver": FieldSpec(default=None), + "region": FieldSpec(default=None), + "aws_access_key_id": FieldSpec(default=None), + "aws_secret_access_key": FieldSpec(default=None), + "aws_session_token": FieldSpec(default=None), + "user_agent_extra": FieldSpec(default=None), + "sdk_ua_app_id": FieldSpec(default=None), + **AsyncAwsConfig._FIELDS, + "endpoint_uri": FieldSpec( + default=None, resolver=EndpointUriResolver("json_protocol") + ), + "endpoint_resolver": FieldSpec( + default_factory=lambda: StandardRegionalEndpointsResolver( + endpoint_prefix="jsonprotocol" + ) + ), + "protocol": FieldSpec( + default_factory=lambda: AwsJson11ClientProtocol(_SCHEMA_JSON_PROTOCOL) + ), + "auth_schemes": FieldSpec( + default_factory=lambda: { + ShapeID("aws.auth#sigv4"): SigV4AuthScheme(service="jsonprotocol") + } + ), + "auth_scheme_resolver": FieldSpec(default_factory=HTTPAuthSchemeResolver), + "transport": FieldSpec(default_factory=lambda: AIOHTTPClient()), + } + + def set_auth_scheme(self, scheme: AuthScheme[Any, Any, Any, Any]) -> None: + """ + Set an auth scheme implementation using its scheme ID. :param scheme: + The auth scheme to add or replace. + """ + auth_schemes = dict(self.auth_schemes or {}) + auth_schemes[scheme.scheme_id] = scheme + self.auth_schemes = auth_schemes + + @classmethod + async def resolve( # pyright: ignore[reportIncompatibleMethodOverride] + cls, + *, + profile: str | None = None, + fs: FileSystem | None = None, + config_file_path: str | None = None, + credentials_file_path: str | None = None, + **overrides: Unpack[_AsyncJsonProtocolConfigOverrides], + ) -> Self: + """ + Resolve config from environment, config files, defaults, and explicit + overrides. + """ + return await cls._resolve( + profile=profile, + fs=fs, + config_file_path=config_file_path, + credentials_file_path=credentials_file_path, + overrides=overrides, + ) + + +Plugin: TypeAlias = Callable[[AsyncJsonProtocolConfig], None] +""" +A callable that customizes a client configuration. Service-level plugins +are applied once to the base configuration inherited by every operation. +Operation-level plugins apply only to a single operation invocation. +""" diff --git a/codegen-output/aws-json-1-1/src/awsjson11/models.py b/codegen-output/aws-json-1-1/src/awsjson11/models.py new file mode 100644 index 000000000..9f0eb434e --- /dev/null +++ b/codegen-output/aws-json-1-1/src/awsjson11/models.py @@ -0,0 +1,4187 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from dataclasses import dataclass +from datetime import datetime +from enum import IntEnum, StrEnum +import logging +from typing import Any, Literal, Self, Union + +from smithy_core.deserializers import ShapeDeserializer +from smithy_core.documents import Document, TypeRegistry +from smithy_core.exceptions import ModeledError, SerializationError +from smithy_core.schemas import APIOperation, Schema +from smithy_core.serializers import ShapeSerializer +from smithy_core.shapes import ShapeID +from smithy_core.types import JsonString, UnknownEnumMixin + +from ._private.schemas import ( + COMPLEX_ERROR as _SCHEMA_COMPLEX_ERROR, + COMPLEX_NESTED_ERROR_DATA as _SCHEMA_COMPLEX_NESTED_ERROR_DATA, + CONTENT_TYPE_PARAMETERS as _SCHEMA_CONTENT_TYPE_PARAMETERS, + CONTENT_TYPE_PARAMETERS_INPUT as _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, + CONTENT_TYPE_PARAMETERS_OUTPUT as _SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, + DATETIME_OFFSETS as _SCHEMA_DATETIME_OFFSETS, + DATETIME_OFFSETS_INPUT as _SCHEMA_DATETIME_OFFSETS_INPUT, + DATETIME_OFFSETS_OUTPUT as _SCHEMA_DATETIME_OFFSETS_OUTPUT, + EMPTY_OPERATION as _SCHEMA_EMPTY_OPERATION, + EMPTY_OPERATION_INPUT as _SCHEMA_EMPTY_OPERATION_INPUT, + EMPTY_OPERATION_OUTPUT as _SCHEMA_EMPTY_OPERATION_OUTPUT, + EMPTY_STRUCT as _SCHEMA_EMPTY_STRUCT, + ENDPOINT_OPERATION as _SCHEMA_ENDPOINT_OPERATION, + ENDPOINT_OPERATION_INPUT as _SCHEMA_ENDPOINT_OPERATION_INPUT, + ENDPOINT_OPERATION_OUTPUT as _SCHEMA_ENDPOINT_OPERATION_OUTPUT, + ENDPOINT_WITH_HOST_LABEL_OPERATION as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION, + ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, + ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, + ERROR_WITHOUT_MEMBERS as _SCHEMA_ERROR_WITHOUT_MEMBERS, + ERROR_WITH_MEMBERS as _SCHEMA_ERROR_WITH_MEMBERS, + FOO_ERROR as _SCHEMA_FOO_ERROR, + FRACTIONAL_SECONDS as _SCHEMA_FRACTIONAL_SECONDS, + FRACTIONAL_SECONDS_INPUT as _SCHEMA_FRACTIONAL_SECONDS_INPUT, + FRACTIONAL_SECONDS_OUTPUT as _SCHEMA_FRACTIONAL_SECONDS_OUTPUT, + GREETING_STRUCT as _SCHEMA_GREETING_STRUCT, + GREETING_WITH_ERRORS as _SCHEMA_GREETING_WITH_ERRORS, + GREETING_WITH_ERRORS_INPUT as _SCHEMA_GREETING_WITH_ERRORS_INPUT, + GREETING_WITH_ERRORS_OUTPUT as _SCHEMA_GREETING_WITH_ERRORS_OUTPUT, + HOST_WITH_PATH_OPERATION as _SCHEMA_HOST_WITH_PATH_OPERATION, + HOST_WITH_PATH_OPERATION_INPUT as _SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, + HOST_WITH_PATH_OPERATION_OUTPUT as _SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, + INVALID_GREETING as _SCHEMA_INVALID_GREETING, + JSON_ENUMS as _SCHEMA_JSON_ENUMS, + JSON_ENUMS_INPUT as _SCHEMA_JSON_ENUMS_INPUT, + JSON_ENUMS_OUTPUT as _SCHEMA_JSON_ENUMS_OUTPUT, + JSON_INT_ENUMS as _SCHEMA_JSON_INT_ENUMS, + JSON_INT_ENUMS_INPUT as _SCHEMA_JSON_INT_ENUMS_INPUT, + JSON_INT_ENUMS_OUTPUT as _SCHEMA_JSON_INT_ENUMS_OUTPUT, + JSON_UNIONS as _SCHEMA_JSON_UNIONS, + JSON_UNIONS_INPUT as _SCHEMA_JSON_UNIONS_INPUT, + JSON_UNIONS_OUTPUT as _SCHEMA_JSON_UNIONS_OUTPUT, + KITCHEN_SINK as _SCHEMA_KITCHEN_SINK, + KITCHEN_SINK_OPERATION as _SCHEMA_KITCHEN_SINK_OPERATION, + KITCHEN_SINK_OPERATION_INPUT as _SCHEMA_KITCHEN_SINK_OPERATION_INPUT, + KITCHEN_SINK_OPERATION_OUTPUT as _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT, + MY_UNION as _SCHEMA_MY_UNION, + NULL_OPERATION as _SCHEMA_NULL_OPERATION, + NULL_OPERATION_INPUT as _SCHEMA_NULL_OPERATION_INPUT, + NULL_OPERATION_OUTPUT as _SCHEMA_NULL_OPERATION_OUTPUT, + OPERATION_WITH_OPTIONAL_INPUT_OUTPUT as _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT, + OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_INPUT as _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_INPUT, + OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_OUTPUT as _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_OUTPUT, + PUT_AND_GET_INLINE_DOCUMENTS as _SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS, + PUT_AND_GET_INLINE_DOCUMENTS_INPUT as _SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_INPUT, + PUT_AND_GET_INLINE_DOCUMENTS_OUTPUT as _SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_OUTPUT, + PUT_WITH_CONTENT_ENCODING as _SCHEMA_PUT_WITH_CONTENT_ENCODING, + PUT_WITH_CONTENT_ENCODING_INPUT as _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, + PUT_WITH_CONTENT_ENCODING_OUTPUT as _SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, + SIMPLE_SCALAR_PROPERTIES as _SCHEMA_SIMPLE_SCALAR_PROPERTIES, + SIMPLE_SCALAR_PROPERTIES_INPUT as _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, + SIMPLE_SCALAR_PROPERTIES_OUTPUT as _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, + SIMPLE_STRUCT as _SCHEMA_SIMPLE_STRUCT, + SPARSE_NULLS_OPERATION as _SCHEMA_SPARSE_NULLS_OPERATION, + SPARSE_NULLS_OPERATION_INPUT as _SCHEMA_SPARSE_NULLS_OPERATION_INPUT, + SPARSE_NULLS_OPERATION_OUTPUT as _SCHEMA_SPARSE_NULLS_OPERATION_OUTPUT, + STRUCT_WITH_JSON_NAME as _SCHEMA_STRUCT_WITH_JSON_NAME, +) + + +logger = logging.getLogger(__name__) + + +class ServiceError(ModeledError): + """ + Base error for all errors in the service. + + Some exceptions do not extend from this class, including + synthetic, implicit, and shared exception types. + """ + + +@dataclass(kw_only=True) +class ComplexNestedErrorData: + """Dataclass for ComplexNestedErrorData structure.""" + + foo: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_COMPLEX_NESTED_ERROR_DATA, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_COMPLEX_NESTED_ERROR_DATA.members["Foo"], self.foo + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_COMPLEX_NESTED_ERROR_DATA.members["Foo"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_COMPLEX_NESTED_ERROR_DATA, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ComplexError(ServiceError): + """This error is thrown when a request is invalid.""" + + fault: Literal["client", "server"] | None = "client" + + top_level: str | None = None + + nested: ComplexNestedErrorData | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_COMPLEX_ERROR, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.top_level is not None: + serializer.write_string( + _SCHEMA_COMPLEX_ERROR.members["TopLevel"], self.top_level + ) + + if self.nested is not None: + serializer.write_struct( + _SCHEMA_COMPLEX_ERROR.members["Nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["top_level"] = de.read_string( + _SCHEMA_COMPLEX_ERROR.members["TopLevel"] + ) + + case 1: + kwargs["nested"] = ComplexNestedErrorData.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_COMPLEX_ERROR, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ContentTypeParametersInput: + """Dataclass for ContentTypeParametersInput structure.""" + + value: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.value is not None: + serializer.write_integer( + _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT.members["value"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = de.read_integer( + _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT.members["value"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class ContentTypeParametersOutput: + """Dataclass for ContentTypeParametersOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, consumer=_consumer + ) + return kwargs + + +CONTENT_TYPE_PARAMETERS = APIOperation( + input=ContentTypeParametersInput, + output=ContentTypeParametersOutput, + schema=_SCHEMA_CONTENT_TYPE_PARAMETERS, + input_schema=_SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, + output_schema=_SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class DatetimeOffsetsInput: + """Dataclass for DatetimeOffsetsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DATETIME_OFFSETS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DATETIME_OFFSETS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class DatetimeOffsetsOutput: + """Dataclass for DatetimeOffsetsOutput structure.""" + + datetime_: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DATETIME_OFFSETS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.datetime_ is not None: + serializer.write_timestamp( + _SCHEMA_DATETIME_OFFSETS_OUTPUT.members["datetime"], self.datetime_ + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["datetime_"] = de.read_timestamp( + _SCHEMA_DATETIME_OFFSETS_OUTPUT.members["datetime"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DATETIME_OFFSETS_OUTPUT, consumer=_consumer) + return kwargs + + +DATETIME_OFFSETS = APIOperation( + input=DatetimeOffsetsInput, + output=DatetimeOffsetsOutput, + schema=_SCHEMA_DATETIME_OFFSETS, + input_schema=_SCHEMA_DATETIME_OFFSETS_INPUT, + output_schema=_SCHEMA_DATETIME_OFFSETS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EmptyOperationInput: + """Dataclass for EmptyOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EMPTY_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_EMPTY_OPERATION_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class EmptyOperationOutput: + """Dataclass for EmptyOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EMPTY_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_EMPTY_OPERATION_OUTPUT, consumer=_consumer) + return kwargs + + +EMPTY_OPERATION = APIOperation( + input=EmptyOperationInput, + output=EmptyOperationOutput, + schema=_SCHEMA_EMPTY_OPERATION, + input_schema=_SCHEMA_EMPTY_OPERATION_INPUT, + output_schema=_SCHEMA_EMPTY_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EmptyStruct: + """Dataclass for EmptyStruct structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EMPTY_STRUCT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_EMPTY_STRUCT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class EndpointOperationInput: + """Dataclass for EndpointOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ENDPOINT_OPERATION_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class EndpointOperationOutput: + """Dataclass for EndpointOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ENDPOINT_OPERATION_OUTPUT, consumer=_consumer) + return kwargs + + +ENDPOINT_OPERATION = APIOperation( + input=EndpointOperationInput, + output=EndpointOperationOutput, + schema=_SCHEMA_ENDPOINT_OPERATION, + input_schema=_SCHEMA_ENDPOINT_OPERATION_INPUT, + output_schema=_SCHEMA_ENDPOINT_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EndpointWithHostLabelOperationInput: + """Dataclass for EndpointWithHostLabelOperationInput structure.""" + + label: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.label is not None: + serializer.write_string( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT.members["label"], + self.label, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["label"] = de.read_string( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT.members[ + "label" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class EndpointWithHostLabelOperationOutput: + """Dataclass for EndpointWithHostLabelOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +ENDPOINT_WITH_HOST_LABEL_OPERATION = APIOperation( + input=EndpointWithHostLabelOperationInput, + output=EndpointWithHostLabelOperationOutput, + schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION, + input_schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, + output_schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_list_of_strings( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_list_of_strings( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_list_of_list_of_strings( + serializer: ShapeSerializer, schema: Schema, value: list[list[str]] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + _serialize_list_of_strings(ls, member_schema, e) + + +def _deserialize_list_of_list_of_strings( + deserializer: ShapeDeserializer, schema: Schema +) -> list[list[str]]: + result: list[list[str]] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(_deserialize_list_of_strings(d, member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_map_of_strings( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_map_of_strings( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_list_of_maps_of_strings( + serializer: ShapeSerializer, schema: Schema, value: list[dict[str, str]] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + _serialize_map_of_strings(ls, member_schema, e) + + +def _deserialize_list_of_maps_of_strings( + deserializer: ShapeDeserializer, schema: Schema +) -> list[dict[str, str]]: + result: list[dict[str, str]] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(_deserialize_map_of_strings(d, member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class SimpleStruct: + """Dataclass for SimpleStruct structure.""" + + value: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_STRUCT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.value is not None: + serializer.write_string(_SCHEMA_SIMPLE_STRUCT.members["Value"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = de.read_string( + _SCHEMA_SIMPLE_STRUCT.members["Value"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_SIMPLE_STRUCT, consumer=_consumer) + return kwargs + + +def _serialize_list_of_structs( + serializer: ShapeSerializer, schema: Schema, value: list[SimpleStruct] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_struct(member_schema, e) + + +def _deserialize_list_of_structs( + deserializer: ShapeDeserializer, schema: Schema +) -> list[SimpleStruct]: + result: list[SimpleStruct] = [] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(SimpleStruct.deserialize(d)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_map_of_lists_of_strings( + serializer: ShapeSerializer, schema: Schema, value: dict[str, list[str]] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: _serialize_list_of_strings(vs, value_schema, v)) + + +def _deserialize_map_of_lists_of_strings( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, list[str]]: + result: dict[str, list[str]] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = _deserialize_list_of_strings(d, value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_map_of_map_of_strings( + serializer: ShapeSerializer, schema: Schema, value: dict[str, dict[str, str]] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: _serialize_map_of_strings(vs, value_schema, v)) + + +def _deserialize_map_of_map_of_strings( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, dict[str, str]]: + result: dict[str, dict[str, str]] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = _deserialize_map_of_strings(d, value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_map_of_structs( + serializer: ShapeSerializer, schema: Schema, value: dict[str, SimpleStruct] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_struct(value_schema, v)) + + +def _deserialize_map_of_structs( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, SimpleStruct]: + result: dict[str, SimpleStruct] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = SimpleStruct.deserialize(d) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class StructWithJsonName: + """Dataclass for StructWithJsonName structure.""" + + value: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STRUCT_WITH_JSON_NAME, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.value is not None: + serializer.write_string( + _SCHEMA_STRUCT_WITH_JSON_NAME.members["Value"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = de.read_string( + _SCHEMA_STRUCT_WITH_JSON_NAME.members["Value"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_STRUCT_WITH_JSON_NAME, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ErrorWithoutMembers(ServiceError): + """Dataclass for ErrorWithoutMembers structure.""" + + fault: Literal["client", "server"] | None = "server" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ERROR_WITHOUT_MEMBERS, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ERROR_WITHOUT_MEMBERS, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class FooError(ServiceError): + """ + This error has test cases that test some of the dark corners of Amazon + service framework history. It should only be implemented by clients. + """ + + fault: Literal["client", "server"] | None = "server" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FOO_ERROR, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FOO_ERROR, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class FractionalSecondsInput: + """Dataclass for FractionalSecondsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FRACTIONAL_SECONDS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FRACTIONAL_SECONDS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class FractionalSecondsOutput: + """Dataclass for FractionalSecondsOutput structure.""" + + datetime_: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FRACTIONAL_SECONDS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.datetime_ is not None: + serializer.write_timestamp( + _SCHEMA_FRACTIONAL_SECONDS_OUTPUT.members["datetime"], self.datetime_ + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["datetime_"] = de.read_timestamp( + _SCHEMA_FRACTIONAL_SECONDS_OUTPUT.members["datetime"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FRACTIONAL_SECONDS_OUTPUT, consumer=_consumer) + return kwargs + + +FRACTIONAL_SECONDS = APIOperation( + input=FractionalSecondsInput, + output=FractionalSecondsOutput, + schema=_SCHEMA_FRACTIONAL_SECONDS, + input_schema=_SCHEMA_FRACTIONAL_SECONDS_INPUT, + output_schema=_SCHEMA_FRACTIONAL_SECONDS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class GreetingWithErrorsInput: + """Dataclass for GreetingWithErrorsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_WITH_ERRORS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_GREETING_WITH_ERRORS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class GreetingWithErrorsOutput: + """Dataclass for GreetingWithErrorsOutput structure.""" + + greeting: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_WITH_ERRORS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.greeting is not None: + serializer.write_string( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT.members["greeting"], self.greeting + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["greeting"] = de.read_string( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT.members["greeting"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class InvalidGreeting(ServiceError): + """This error is thrown when an invalid greeting value is provided.""" + + fault: Literal["client", "server"] | None = "client" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INVALID_GREETING, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.message is not None: + serializer.write_string( + _SCHEMA_INVALID_GREETING.members["Message"], self.message + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["message"] = de.read_string( + _SCHEMA_INVALID_GREETING.members["Message"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_INVALID_GREETING, consumer=_consumer) + return kwargs + + +GREETING_WITH_ERRORS = APIOperation( + input=GreetingWithErrorsInput, + output=GreetingWithErrorsOutput, + schema=_SCHEMA_GREETING_WITH_ERRORS, + input_schema=_SCHEMA_GREETING_WITH_ERRORS_INPUT, + output_schema=_SCHEMA_GREETING_WITH_ERRORS_OUTPUT, + error_registry=TypeRegistry( + { + ShapeID("aws.protocoltests.json#InvalidGreeting"): InvalidGreeting, + ShapeID("aws.protocoltests.json#ComplexError"): ComplexError, + ShapeID("aws.protocoltests.json#FooError"): FooError, + } + ), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[_SCHEMA_INVALID_GREETING, _SCHEMA_COMPLEX_ERROR, _SCHEMA_FOO_ERROR], +) + + +@dataclass(kw_only=True) +class HostWithPathOperationInput: + """Dataclass for HostWithPathOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HostWithPathOperationOutput: + """Dataclass for HostWithPathOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +HOST_WITH_PATH_OPERATION = APIOperation( + input=HostWithPathOperationInput, + output=HostWithPathOperationOutput, + schema=_SCHEMA_HOST_WITH_PATH_OPERATION, + input_schema=_SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, + output_schema=_SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +class FooEnum(UnknownEnumMixin, StrEnum): + FOO = "Foo" + BAZ = "Baz" + BAR = "Bar" + ONE = "1" + ZERO = "0" + + +def _serialize_foo_enum_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_foo_enum_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(FooEnum(d.read_string(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_foo_enum_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_foo_enum_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = FooEnum(d.read_string(value_schema)) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_foo_enum_set( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_foo_enum_set( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(FooEnum(d.read_string(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class JsonEnumsInput: + """Dataclass for JsonEnumsInput structure.""" + + foo_enum1: str | None = None + + foo_enum2: str | None = None + + foo_enum3: str | None = None + + foo_enum_list: list[str] | None = None + + foo_enum_set: list[str] | None = None + + foo_enum_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_ENUMS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo_enum1 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnum1"], self.foo_enum1 + ) + + if self.foo_enum2 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnum2"], self.foo_enum2 + ) + + if self.foo_enum3 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnum3"], self.foo_enum3 + ) + + if self.foo_enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumList"], + self.foo_enum_list, + ) + + if self.foo_enum_set is not None: + _serialize_foo_enum_set( + serializer, + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumSet"], + self.foo_enum_set, + ) + + if self.foo_enum_map is not None: + _serialize_foo_enum_map( + serializer, + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumMap"], + self.foo_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo_enum1"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_INPUT.members["fooEnum1"]) + ) + + case 1: + kwargs["foo_enum2"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_INPUT.members["fooEnum2"]) + ) + + case 2: + kwargs["foo_enum3"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_INPUT.members["fooEnum3"]) + ) + + case 3: + kwargs["foo_enum_list"] = _deserialize_foo_enum_list( + de, _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumList"] + ) + + case 4: + kwargs["foo_enum_set"] = _deserialize_foo_enum_set( + de, _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumSet"] + ) + + case 5: + kwargs["foo_enum_map"] = _deserialize_foo_enum_map( + de, _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_ENUMS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonEnumsOutput: + """Dataclass for JsonEnumsOutput structure.""" + + foo_enum1: str | None = None + + foo_enum2: str | None = None + + foo_enum3: str | None = None + + foo_enum_list: list[str] | None = None + + foo_enum_set: list[str] | None = None + + foo_enum_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_ENUMS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo_enum1 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum1"], self.foo_enum1 + ) + + if self.foo_enum2 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum2"], self.foo_enum2 + ) + + if self.foo_enum3 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum3"], self.foo_enum3 + ) + + if self.foo_enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumList"], + self.foo_enum_list, + ) + + if self.foo_enum_set is not None: + _serialize_foo_enum_set( + serializer, + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumSet"], + self.foo_enum_set, + ) + + if self.foo_enum_map is not None: + _serialize_foo_enum_map( + serializer, + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumMap"], + self.foo_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo_enum1"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum1"]) + ) + + case 1: + kwargs["foo_enum2"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum2"]) + ) + + case 2: + kwargs["foo_enum3"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum3"]) + ) + + case 3: + kwargs["foo_enum_list"] = _deserialize_foo_enum_list( + de, _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumList"] + ) + + case 4: + kwargs["foo_enum_set"] = _deserialize_foo_enum_set( + de, _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumSet"] + ) + + case 5: + kwargs["foo_enum_map"] = _deserialize_foo_enum_map( + de, _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_ENUMS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_ENUMS = APIOperation( + input=JsonEnumsInput, + output=JsonEnumsOutput, + schema=_SCHEMA_JSON_ENUMS, + input_schema=_SCHEMA_JSON_ENUMS_INPUT, + output_schema=_SCHEMA_JSON_ENUMS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +class IntegerEnum(UnknownEnumMixin, IntEnum): + A = 1 + B = 2 + C = 3 + + +def _serialize_integer_enum_list( + serializer: ShapeSerializer, schema: Schema, value: list[int] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_integer(member_schema, e) + + +def _deserialize_integer_enum_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int]: + result: list[int] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(IntegerEnum(d.read_integer(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_integer_enum_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, int] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_integer(value_schema, v)) + + +def _deserialize_integer_enum_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, int]: + result: dict[str, int] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = IntegerEnum(d.read_integer(value_schema)) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_integer_enum_set( + serializer: ShapeSerializer, schema: Schema, value: list[int] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_integer(member_schema, e) + + +def _deserialize_integer_enum_set( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int]: + result: list[int] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(IntegerEnum(d.read_integer(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class JsonIntEnumsInput: + """Dataclass for JsonIntEnumsInput structure.""" + + int_enum1: int | None = None + + int_enum2: int | None = None + + int_enum3: int | None = None + + int_enum_list: list[int] | None = None + + int_enum_set: list[int] | None = None + + int_enum_map: dict[str, int] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_INT_ENUMS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.int_enum1 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnum1"], self.int_enum1 + ) + + if self.int_enum2 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnum2"], self.int_enum2 + ) + + if self.int_enum3 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnum3"], self.int_enum3 + ) + + if self.int_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnumList"], + self.int_enum_list, + ) + + if self.int_enum_set is not None: + _serialize_integer_enum_set( + serializer, + _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnumSet"], + self.int_enum_set, + ) + + if self.int_enum_map is not None: + _serialize_integer_enum_map( + serializer, + _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnumMap"], + self.int_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["int_enum1"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnum1"] + ) + ) + + case 1: + kwargs["int_enum2"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnum2"] + ) + ) + + case 2: + kwargs["int_enum3"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnum3"] + ) + ) + + case 3: + kwargs["int_enum_list"] = _deserialize_integer_enum_list( + de, _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnumList"] + ) + + case 4: + kwargs["int_enum_set"] = _deserialize_integer_enum_set( + de, _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnumSet"] + ) + + case 5: + kwargs["int_enum_map"] = _deserialize_integer_enum_map( + de, _SCHEMA_JSON_INT_ENUMS_INPUT.members["intEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_INT_ENUMS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonIntEnumsOutput: + """Dataclass for JsonIntEnumsOutput structure.""" + + int_enum1: int | None = None + + int_enum2: int | None = None + + int_enum3: int | None = None + + int_enum_list: list[int] | None = None + + int_enum_set: list[int] | None = None + + int_enum_map: dict[str, int] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_INT_ENUMS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.int_enum1 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnum1"], self.int_enum1 + ) + + if self.int_enum2 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnum2"], self.int_enum2 + ) + + if self.int_enum3 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnum3"], self.int_enum3 + ) + + if self.int_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnumList"], + self.int_enum_list, + ) + + if self.int_enum_set is not None: + _serialize_integer_enum_set( + serializer, + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnumSet"], + self.int_enum_set, + ) + + if self.int_enum_map is not None: + _serialize_integer_enum_map( + serializer, + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnumMap"], + self.int_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["int_enum1"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnum1"] + ) + ) + + case 1: + kwargs["int_enum2"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnum2"] + ) + ) + + case 2: + kwargs["int_enum3"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnum3"] + ) + ) + + case 3: + kwargs["int_enum_list"] = _deserialize_integer_enum_list( + de, _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnumList"] + ) + + case 4: + kwargs["int_enum_set"] = _deserialize_integer_enum_set( + de, _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnumSet"] + ) + + case 5: + kwargs["int_enum_map"] = _deserialize_integer_enum_map( + de, _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["intEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_INT_ENUMS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_INT_ENUMS = APIOperation( + input=JsonIntEnumsInput, + output=JsonIntEnumsOutput, + schema=_SCHEMA_JSON_INT_ENUMS, + input_schema=_SCHEMA_JSON_INT_ENUMS_INPUT, + output_schema=_SCHEMA_JSON_INT_ENUMS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class GreetingStruct: + """Dataclass for GreetingStruct structure.""" + + hi: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_STRUCT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.hi is not None: + serializer.write_string(_SCHEMA_GREETING_STRUCT.members["hi"], self.hi) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["hi"] = de.read_string(_SCHEMA_GREETING_STRUCT.members["hi"]) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_GREETING_STRUCT, consumer=_consumer) + return kwargs + + +@dataclass +class MyUnionStringValue: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_MY_UNION.members["stringValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_MY_UNION.members["stringValue"]) + ) + + +@dataclass +class MyUnionBooleanValue: + value: bool + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_boolean(_SCHEMA_MY_UNION.members["booleanValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_boolean(_SCHEMA_MY_UNION.members["booleanValue"]) + ) + + +@dataclass +class MyUnionNumberValue: + value: int + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_integer(_SCHEMA_MY_UNION.members["numberValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_integer(_SCHEMA_MY_UNION.members["numberValue"]) + ) + + +@dataclass +class MyUnionBlobValue: + value: bytes + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_blob(_SCHEMA_MY_UNION.members["blobValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=deserializer.read_blob(_SCHEMA_MY_UNION.members["blobValue"])) + + +@dataclass +class MyUnionTimestampValue: + value: datetime + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_timestamp( + _SCHEMA_MY_UNION.members["timestampValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_timestamp( + _SCHEMA_MY_UNION.members["timestampValue"] + ) + ) + + +@dataclass +class MyUnionEnumValue: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_MY_UNION.members["enumValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=FooEnum( + deserializer.read_string(_SCHEMA_MY_UNION.members["enumValue"]) + ) + ) + + +@dataclass +class MyUnionListValue: + value: list[str] + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + _serialize_string_list( + serializer, _SCHEMA_MY_UNION.members["listValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=_deserialize_string_list( + deserializer, _SCHEMA_MY_UNION.members["listValue"] + ) + ) + + +@dataclass +class MyUnionMapValue: + value: dict[str, str] + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + _serialize_string_map( + serializer, _SCHEMA_MY_UNION.members["mapValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=_deserialize_string_map( + deserializer, _SCHEMA_MY_UNION.members["mapValue"] + ) + ) + + +@dataclass +class MyUnionStructureValue: + value: GreetingStruct + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION.members["structureValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=GreetingStruct.deserialize(deserializer)) + + +@dataclass +class MyUnionUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +MyUnion = Union[ + MyUnionStringValue + | MyUnionBooleanValue + | MyUnionNumberValue + | MyUnionBlobValue + | MyUnionTimestampValue + | MyUnionEnumValue + | MyUnionListValue + | MyUnionMapValue + | MyUnionStructureValue + | MyUnionUnknown +] +"""A union with a representative set of types for members.""" + + +class _MyUnionDeserializer: + _result: MyUnion | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> MyUnion: + self._result = None + deserializer.read_struct(_SCHEMA_MY_UNION, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(MyUnionStringValue.deserialize(de)) + + case 1: + self._set_result(MyUnionBooleanValue.deserialize(de)) + + case 2: + self._set_result(MyUnionNumberValue.deserialize(de)) + + case 3: + self._set_result(MyUnionBlobValue.deserialize(de)) + + case 4: + self._set_result(MyUnionTimestampValue.deserialize(de)) + + case 5: + self._set_result(MyUnionEnumValue.deserialize(de)) + + case 6: + self._set_result(MyUnionListValue.deserialize(de)) + + case 7: + self._set_result(MyUnionMapValue.deserialize(de)) + + case 8: + self._set_result(MyUnionStructureValue.deserialize(de)) + + case _: + self._set_result(MyUnionUnknown(tag=schema.expect_member_name())) + + def _set_result(self, value: MyUnion) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class JsonUnionsInput: + """A shared structure that contains a single union member.""" + + contents: MyUnion | None = None + """A union with a representative set of types for members.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_UNIONS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.contents is not None: + serializer.write_struct( + _SCHEMA_JSON_UNIONS_INPUT.members["contents"], self.contents + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["contents"] = _MyUnionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_UNIONS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonUnionsOutput: + """A shared structure that contains a single union member.""" + + contents: MyUnion | None = None + """A union with a representative set of types for members.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_UNIONS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.contents is not None: + serializer.write_struct( + _SCHEMA_JSON_UNIONS_OUTPUT.members["contents"], self.contents + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["contents"] = _MyUnionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_UNIONS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_UNIONS = APIOperation( + input=JsonUnionsInput, + output=JsonUnionsOutput, + schema=_SCHEMA_JSON_UNIONS, + input_schema=_SCHEMA_JSON_UNIONS_INPUT, + output_schema=_SCHEMA_JSON_UNIONS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NullOperationInput: + """Dataclass for NullOperationInput structure.""" + + string: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NULL_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string is not None: + serializer.write_string( + _SCHEMA_NULL_OPERATION_INPUT.members["string"], self.string + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string"] = de.read_string( + _SCHEMA_NULL_OPERATION_INPUT.members["string"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NULL_OPERATION_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class NullOperationOutput: + """Dataclass for NullOperationOutput structure.""" + + string: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NULL_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string is not None: + serializer.write_string( + _SCHEMA_NULL_OPERATION_OUTPUT.members["string"], self.string + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string"] = de.read_string( + _SCHEMA_NULL_OPERATION_OUTPUT.members["string"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NULL_OPERATION_OUTPUT, consumer=_consumer) + return kwargs + + +NULL_OPERATION = APIOperation( + input=NullOperationInput, + output=NullOperationOutput, + schema=_SCHEMA_NULL_OPERATION, + input_schema=_SCHEMA_NULL_OPERATION_INPUT, + output_schema=_SCHEMA_NULL_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class OperationWithOptionalInputOutputInput: + """Dataclass for OperationWithOptionalInputOutputInput structure.""" + + value: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_INPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.value is not None: + serializer.write_string( + _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_INPUT.members["Value"], + self.value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = de.read_string( + _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_INPUT.members[ + "Value" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class OperationWithOptionalInputOutputOutput: + """Dataclass for OperationWithOptionalInputOutputOutput structure.""" + + value: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.value is not None: + serializer.write_string( + _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_OUTPUT.members["Value"], + self.value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = de.read_string( + _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_OUTPUT.members[ + "Value" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_OUTPUT, consumer=_consumer + ) + return kwargs + + +OPERATION_WITH_OPTIONAL_INPUT_OUTPUT = APIOperation( + input=OperationWithOptionalInputOutputInput, + output=OperationWithOptionalInputOutputOutput, + schema=_SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT, + input_schema=_SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_INPUT, + output_schema=_SCHEMA_OPERATION_WITH_OPTIONAL_INPUT_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class PutAndGetInlineDocumentsInput: + """Dataclass for PutAndGetInlineDocumentsInput structure.""" + + inline_document: Document | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.inline_document is not None: + serializer.write_document( + _SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_INPUT.members["inlineDocument"], + self.inline_document, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["inline_document"] = de.read_document( + _SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_INPUT.members[ + "inlineDocument" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class PutAndGetInlineDocumentsOutput: + """Dataclass for PutAndGetInlineDocumentsOutput structure.""" + + inline_document: Document | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.inline_document is not None: + serializer.write_document( + _SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_OUTPUT.members["inlineDocument"], + self.inline_document, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["inline_document"] = de.read_document( + _SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_OUTPUT.members[ + "inlineDocument" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_OUTPUT, consumer=_consumer + ) + return kwargs + + +PUT_AND_GET_INLINE_DOCUMENTS = APIOperation( + input=PutAndGetInlineDocumentsInput, + output=PutAndGetInlineDocumentsOutput, + schema=_SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS, + input_schema=_SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_INPUT, + output_schema=_SCHEMA_PUT_AND_GET_INLINE_DOCUMENTS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class PutWithContentEncodingInput: + """Dataclass for PutWithContentEncodingInput structure.""" + + encoding: str | None = None + + data: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.encoding is not None: + serializer.write_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["encoding"], + self.encoding, + ) + + if self.data is not None: + serializer.write_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["data"], self.data + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["encoding"] = de.read_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["encoding"] + ) + + case 1: + kwargs["data"] = de.read_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class PutWithContentEncodingOutput: + """Dataclass for PutWithContentEncodingOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, consumer=_consumer + ) + return kwargs + + +PUT_WITH_CONTENT_ENCODING = APIOperation( + input=PutWithContentEncodingInput, + output=PutWithContentEncodingOutput, + schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING, + input_schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, + output_schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class SimpleScalarPropertiesInput: + """Dataclass for SimpleScalarPropertiesInput structure.""" + + float_value: float | None = None + + double_value: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.float_value is not None: + serializer.write_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["floatValue"], + self.float_value, + ) + + if self.double_value is not None: + serializer.write_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["doubleValue"], + self.double_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["float_value"] = de.read_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["floatValue"] + ) + + case 1: + kwargs["double_value"] = de.read_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["doubleValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class SimpleScalarPropertiesOutput: + """Dataclass for SimpleScalarPropertiesOutput structure.""" + + float_value: float | None = None + + double_value: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.float_value is not None: + serializer.write_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["floatValue"], + self.float_value, + ) + + if self.double_value is not None: + serializer.write_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["doubleValue"], + self.double_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["float_value"] = de.read_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["floatValue"] + ) + + case 1: + kwargs["double_value"] = de.read_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["doubleValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, consumer=_consumer + ) + return kwargs + + +SIMPLE_SCALAR_PROPERTIES = APIOperation( + input=SimpleScalarPropertiesInput, + output=SimpleScalarPropertiesOutput, + schema=_SCHEMA_SIMPLE_SCALAR_PROPERTIES, + input_schema=_SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, + output_schema=_SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_sparse_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[str | None] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + if e is None: + ls.write_null(member_schema) + else: + ls.write_string(member_schema, e) + + +def _deserialize_sparse_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str | None]: + result: list[str | None] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + result.append(None) + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_sparse_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str | None] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + if v is None: + m.entry(k, lambda vs: vs.write_null(value_schema)) + else: + m.entry(k, lambda vs: vs.write_string(value_schema, v)) # type: ignore + + +def _deserialize_sparse_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str | None]: + result: dict[str, str | None] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + result[k] = None + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class SparseNullsOperationInput: + """Dataclass for SparseNullsOperationInput structure.""" + + sparse_string_list: list[str | None] | None = None + + sparse_string_map: dict[str, str | None] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SPARSE_NULLS_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.sparse_string_list is not None: + _serialize_sparse_string_list( + serializer, + _SCHEMA_SPARSE_NULLS_OPERATION_INPUT.members["sparseStringList"], + self.sparse_string_list, + ) + + if self.sparse_string_map is not None: + _serialize_sparse_string_map( + serializer, + _SCHEMA_SPARSE_NULLS_OPERATION_INPUT.members["sparseStringMap"], + self.sparse_string_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["sparse_string_list"] = _deserialize_sparse_string_list( + de, + _SCHEMA_SPARSE_NULLS_OPERATION_INPUT.members[ + "sparseStringList" + ], + ) + + case 1: + kwargs["sparse_string_map"] = _deserialize_sparse_string_map( + de, + _SCHEMA_SPARSE_NULLS_OPERATION_INPUT.members["sparseStringMap"], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SPARSE_NULLS_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class SparseNullsOperationOutput: + """Dataclass for SparseNullsOperationOutput structure.""" + + sparse_string_list: list[str | None] | None = None + + sparse_string_map: dict[str, str | None] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SPARSE_NULLS_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.sparse_string_list is not None: + _serialize_sparse_string_list( + serializer, + _SCHEMA_SPARSE_NULLS_OPERATION_OUTPUT.members["sparseStringList"], + self.sparse_string_list, + ) + + if self.sparse_string_map is not None: + _serialize_sparse_string_map( + serializer, + _SCHEMA_SPARSE_NULLS_OPERATION_OUTPUT.members["sparseStringMap"], + self.sparse_string_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["sparse_string_list"] = _deserialize_sparse_string_list( + de, + _SCHEMA_SPARSE_NULLS_OPERATION_OUTPUT.members[ + "sparseStringList" + ], + ) + + case 1: + kwargs["sparse_string_map"] = _deserialize_sparse_string_map( + de, + _SCHEMA_SPARSE_NULLS_OPERATION_OUTPUT.members[ + "sparseStringMap" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SPARSE_NULLS_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +SPARSE_NULLS_OPERATION = APIOperation( + input=SparseNullsOperationInput, + output=SparseNullsOperationOutput, + schema=_SCHEMA_SPARSE_NULLS_OPERATION, + input_schema=_SCHEMA_SPARSE_NULLS_OPERATION_INPUT, + output_schema=_SCHEMA_SPARSE_NULLS_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class KitchenSink: + """Dataclass for KitchenSink structure.""" + + blob: bytes | None = None + + boolean: bool | None = None + + double: float | None = None + + empty_struct: EmptyStruct | None = None + + float_: float | None = None + + httpdate_timestamp: datetime | None = None + + integer: int | None = None + + iso8601_timestamp: datetime | None = None + + json_value: str | JsonString | None = None + + list_of_lists: list[list[str]] | None = None + + list_of_maps_of_strings: list[dict[str, str]] | None = None + + list_of_strings: list[str] | None = None + + list_of_structs: list[SimpleStruct] | None = None + + long: int | None = None + + map_of_lists_of_strings: dict[str, list[str]] | None = None + + map_of_maps: dict[str, dict[str, str]] | None = None + + map_of_strings: dict[str, str] | None = None + + map_of_structs: dict[str, SimpleStruct] | None = None + + recursive_list: "list[KitchenSink] | None" = None + + recursive_map: "dict[str, KitchenSink] | None" = None + + recursive_struct: "KitchenSink | None" = None + + simple_struct: SimpleStruct | None = None + + string: str | None = None + + struct_with_json_name: StructWithJsonName | None = None + + timestamp: datetime | None = None + + unix_timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_KITCHEN_SINK, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.blob is not None: + serializer.write_blob(_SCHEMA_KITCHEN_SINK.members["Blob"], self.blob) + + if self.boolean is not None: + serializer.write_boolean( + _SCHEMA_KITCHEN_SINK.members["Boolean"], self.boolean + ) + + if self.double is not None: + serializer.write_double(_SCHEMA_KITCHEN_SINK.members["Double"], self.double) + + if self.empty_struct is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK.members["EmptyStruct"], self.empty_struct + ) + + if self.float_ is not None: + serializer.write_float(_SCHEMA_KITCHEN_SINK.members["Float"], self.float_) + + if self.httpdate_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK.members["HttpdateTimestamp"], + self.httpdate_timestamp, + ) + + if self.integer is not None: + serializer.write_integer( + _SCHEMA_KITCHEN_SINK.members["Integer"], self.integer + ) + + if self.iso8601_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK.members["Iso8601Timestamp"], self.iso8601_timestamp + ) + + if self.json_value is not None: + serializer.write_string( + _SCHEMA_KITCHEN_SINK.members["JsonValue"], self.json_value + ) + + if self.list_of_lists is not None: + _serialize_list_of_list_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK.members["ListOfLists"], + self.list_of_lists, + ) + + if self.list_of_maps_of_strings is not None: + _serialize_list_of_maps_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK.members["ListOfMapsOfStrings"], + self.list_of_maps_of_strings, + ) + + if self.list_of_strings is not None: + _serialize_list_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK.members["ListOfStrings"], + self.list_of_strings, + ) + + if self.list_of_structs is not None: + _serialize_list_of_structs( + serializer, + _SCHEMA_KITCHEN_SINK.members["ListOfStructs"], + self.list_of_structs, + ) + + if self.long is not None: + serializer.write_long(_SCHEMA_KITCHEN_SINK.members["Long"], self.long) + + if self.map_of_lists_of_strings is not None: + _serialize_map_of_lists_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK.members["MapOfListsOfStrings"], + self.map_of_lists_of_strings, + ) + + if self.map_of_maps is not None: + _serialize_map_of_map_of_strings( + serializer, _SCHEMA_KITCHEN_SINK.members["MapOfMaps"], self.map_of_maps + ) + + if self.map_of_strings is not None: + _serialize_map_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK.members["MapOfStrings"], + self.map_of_strings, + ) + + if self.map_of_structs is not None: + _serialize_map_of_structs( + serializer, + _SCHEMA_KITCHEN_SINK.members["MapOfStructs"], + self.map_of_structs, + ) + + if self.recursive_list is not None: + _serialize_list_of_kitchen_sinks( + serializer, + _SCHEMA_KITCHEN_SINK.members["RecursiveList"], + self.recursive_list, + ) + + if self.recursive_map is not None: + _serialize_map_of_kitchen_sinks( + serializer, + _SCHEMA_KITCHEN_SINK.members["RecursiveMap"], + self.recursive_map, + ) + + if self.recursive_struct is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK.members["RecursiveStruct"], self.recursive_struct + ) + + if self.simple_struct is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK.members["SimpleStruct"], self.simple_struct + ) + + if self.string is not None: + serializer.write_string(_SCHEMA_KITCHEN_SINK.members["String"], self.string) + + if self.struct_with_json_name is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK.members["StructWithJsonName"], + self.struct_with_json_name, + ) + + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK.members["Timestamp"], self.timestamp + ) + + if self.unix_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK.members["UnixTimestamp"], self.unix_timestamp + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["blob"] = de.read_blob(_SCHEMA_KITCHEN_SINK.members["Blob"]) + + case 1: + kwargs["boolean"] = de.read_boolean( + _SCHEMA_KITCHEN_SINK.members["Boolean"] + ) + + case 2: + kwargs["double"] = de.read_double( + _SCHEMA_KITCHEN_SINK.members["Double"] + ) + + case 3: + kwargs["empty_struct"] = EmptyStruct.deserialize(de) + + case 4: + kwargs["float_"] = de.read_float( + _SCHEMA_KITCHEN_SINK.members["Float"] + ) + + case 5: + kwargs["httpdate_timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK.members["HttpdateTimestamp"] + ) + + case 6: + kwargs["integer"] = de.read_integer( + _SCHEMA_KITCHEN_SINK.members["Integer"] + ) + + case 7: + kwargs["iso8601_timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK.members["Iso8601Timestamp"] + ) + + case 8: + kwargs["json_value"] = de.read_string( + _SCHEMA_KITCHEN_SINK.members["JsonValue"] + ) + + case 9: + kwargs["list_of_lists"] = _deserialize_list_of_list_of_strings( + de, _SCHEMA_KITCHEN_SINK.members["ListOfLists"] + ) + + case 10: + kwargs["list_of_maps_of_strings"] = ( + _deserialize_list_of_maps_of_strings( + de, _SCHEMA_KITCHEN_SINK.members["ListOfMapsOfStrings"] + ) + ) + + case 11: + kwargs["list_of_strings"] = _deserialize_list_of_strings( + de, _SCHEMA_KITCHEN_SINK.members["ListOfStrings"] + ) + + case 12: + kwargs["list_of_structs"] = _deserialize_list_of_structs( + de, _SCHEMA_KITCHEN_SINK.members["ListOfStructs"] + ) + + case 13: + kwargs["long"] = de.read_long(_SCHEMA_KITCHEN_SINK.members["Long"]) + + case 14: + kwargs["map_of_lists_of_strings"] = ( + _deserialize_map_of_lists_of_strings( + de, _SCHEMA_KITCHEN_SINK.members["MapOfListsOfStrings"] + ) + ) + + case 15: + kwargs["map_of_maps"] = _deserialize_map_of_map_of_strings( + de, _SCHEMA_KITCHEN_SINK.members["MapOfMaps"] + ) + + case 16: + kwargs["map_of_strings"] = _deserialize_map_of_strings( + de, _SCHEMA_KITCHEN_SINK.members["MapOfStrings"] + ) + + case 17: + kwargs["map_of_structs"] = _deserialize_map_of_structs( + de, _SCHEMA_KITCHEN_SINK.members["MapOfStructs"] + ) + + case 18: + kwargs["recursive_list"] = _deserialize_list_of_kitchen_sinks( + de, _SCHEMA_KITCHEN_SINK.members["RecursiveList"] + ) + + case 19: + kwargs["recursive_map"] = _deserialize_map_of_kitchen_sinks( + de, _SCHEMA_KITCHEN_SINK.members["RecursiveMap"] + ) + + case 20: + kwargs["recursive_struct"] = KitchenSink.deserialize(de) + + case 21: + kwargs["simple_struct"] = SimpleStruct.deserialize(de) + + case 22: + kwargs["string"] = de.read_string( + _SCHEMA_KITCHEN_SINK.members["String"] + ) + + case 23: + kwargs["struct_with_json_name"] = StructWithJsonName.deserialize(de) + + case 24: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK.members["Timestamp"] + ) + + case 25: + kwargs["unix_timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK.members["UnixTimestamp"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_KITCHEN_SINK, consumer=_consumer) + return kwargs + + +def _serialize_list_of_kitchen_sinks( + serializer: ShapeSerializer, schema: Schema, value: list[KitchenSink] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_struct(member_schema, e) + + +def _deserialize_list_of_kitchen_sinks( + deserializer: ShapeDeserializer, schema: Schema +) -> list[KitchenSink]: + result: list[KitchenSink] = [] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(KitchenSink.deserialize(d)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_map_of_kitchen_sinks( + serializer: ShapeSerializer, schema: Schema, value: dict[str, KitchenSink] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_struct(value_schema, v)) + + +def _deserialize_map_of_kitchen_sinks( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, KitchenSink]: + result: dict[str, KitchenSink] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = KitchenSink.deserialize(d) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class ErrorWithMembers(ServiceError): + """Dataclass for ErrorWithMembers structure.""" + + fault: Literal["client", "server"] | None = "client" + + code: str | None = None + + complex_data: "KitchenSink | None" = None + + integer_field: int | None = None + + list_field: list[str] | None = None + + map_field: dict[str, str] | None = None + + string_field: str | None = None + """abc""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ERROR_WITH_MEMBERS, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.code is not None: + serializer.write_string( + _SCHEMA_ERROR_WITH_MEMBERS.members["Code"], self.code + ) + + if self.complex_data is not None: + serializer.write_struct( + _SCHEMA_ERROR_WITH_MEMBERS.members["ComplexData"], self.complex_data + ) + + if self.integer_field is not None: + serializer.write_integer( + _SCHEMA_ERROR_WITH_MEMBERS.members["IntegerField"], self.integer_field + ) + + if self.list_field is not None: + _serialize_list_of_strings( + serializer, + _SCHEMA_ERROR_WITH_MEMBERS.members["ListField"], + self.list_field, + ) + + if self.map_field is not None: + _serialize_map_of_strings( + serializer, + _SCHEMA_ERROR_WITH_MEMBERS.members["MapField"], + self.map_field, + ) + + if self.message is not None: + serializer.write_string( + _SCHEMA_ERROR_WITH_MEMBERS.members["Message"], self.message + ) + + if self.string_field is not None: + serializer.write_string( + _SCHEMA_ERROR_WITH_MEMBERS.members["StringField"], self.string_field + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["code"] = de.read_string( + _SCHEMA_ERROR_WITH_MEMBERS.members["Code"] + ) + + case 1: + kwargs["complex_data"] = KitchenSink.deserialize(de) + + case 2: + kwargs["integer_field"] = de.read_integer( + _SCHEMA_ERROR_WITH_MEMBERS.members["IntegerField"] + ) + + case 3: + kwargs["list_field"] = _deserialize_list_of_strings( + de, _SCHEMA_ERROR_WITH_MEMBERS.members["ListField"] + ) + + case 4: + kwargs["map_field"] = _deserialize_map_of_strings( + de, _SCHEMA_ERROR_WITH_MEMBERS.members["MapField"] + ) + + case 5: + kwargs["message"] = de.read_string( + _SCHEMA_ERROR_WITH_MEMBERS.members["Message"] + ) + + case 6: + kwargs["string_field"] = de.read_string( + _SCHEMA_ERROR_WITH_MEMBERS.members["StringField"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ERROR_WITH_MEMBERS, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class KitchenSinkOperationInput: + """Dataclass for KitchenSinkOperationInput structure.""" + + blob: bytes | None = None + + boolean: bool | None = None + + double: float | None = None + + empty_struct: EmptyStruct | None = None + + float_: float | None = None + + httpdate_timestamp: datetime | None = None + + integer: int | None = None + + iso8601_timestamp: datetime | None = None + + json_value: str | JsonString | None = None + + list_of_lists: list[list[str]] | None = None + + list_of_maps_of_strings: list[dict[str, str]] | None = None + + list_of_strings: list[str] | None = None + + list_of_structs: list[SimpleStruct] | None = None + + long: int | None = None + + map_of_lists_of_strings: dict[str, list[str]] | None = None + + map_of_maps: dict[str, dict[str, str]] | None = None + + map_of_strings: dict[str, str] | None = None + + map_of_structs: dict[str, SimpleStruct] | None = None + + recursive_list: "list[KitchenSink] | None" = None + + recursive_map: "dict[str, KitchenSink] | None" = None + + recursive_struct: "KitchenSink | None" = None + + simple_struct: SimpleStruct | None = None + + string: str | None = None + + struct_with_json_name: StructWithJsonName | None = None + + timestamp: datetime | None = None + + unix_timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_KITCHEN_SINK_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.blob is not None: + serializer.write_blob( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Blob"], self.blob + ) + + if self.boolean is not None: + serializer.write_boolean( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Boolean"], self.boolean + ) + + if self.double is not None: + serializer.write_double( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Double"], self.double + ) + + if self.empty_struct is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["EmptyStruct"], + self.empty_struct, + ) + + if self.float_ is not None: + serializer.write_float( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Float"], self.float_ + ) + + if self.httpdate_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["HttpdateTimestamp"], + self.httpdate_timestamp, + ) + + if self.integer is not None: + serializer.write_integer( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Integer"], self.integer + ) + + if self.iso8601_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Iso8601Timestamp"], + self.iso8601_timestamp, + ) + + if self.json_value is not None: + serializer.write_string( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["JsonValue"], + self.json_value, + ) + + if self.list_of_lists is not None: + _serialize_list_of_list_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["ListOfLists"], + self.list_of_lists, + ) + + if self.list_of_maps_of_strings is not None: + _serialize_list_of_maps_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["ListOfMapsOfStrings"], + self.list_of_maps_of_strings, + ) + + if self.list_of_strings is not None: + _serialize_list_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["ListOfStrings"], + self.list_of_strings, + ) + + if self.list_of_structs is not None: + _serialize_list_of_structs( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["ListOfStructs"], + self.list_of_structs, + ) + + if self.long is not None: + serializer.write_long( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Long"], self.long + ) + + if self.map_of_lists_of_strings is not None: + _serialize_map_of_lists_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["MapOfListsOfStrings"], + self.map_of_lists_of_strings, + ) + + if self.map_of_maps is not None: + _serialize_map_of_map_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["MapOfMaps"], + self.map_of_maps, + ) + + if self.map_of_strings is not None: + _serialize_map_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["MapOfStrings"], + self.map_of_strings, + ) + + if self.map_of_structs is not None: + _serialize_map_of_structs( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["MapOfStructs"], + self.map_of_structs, + ) + + if self.recursive_list is not None: + _serialize_list_of_kitchen_sinks( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["RecursiveList"], + self.recursive_list, + ) + + if self.recursive_map is not None: + _serialize_map_of_kitchen_sinks( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["RecursiveMap"], + self.recursive_map, + ) + + if self.recursive_struct is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["RecursiveStruct"], + self.recursive_struct, + ) + + if self.simple_struct is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["SimpleStruct"], + self.simple_struct, + ) + + if self.string is not None: + serializer.write_string( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["String"], self.string + ) + + if self.struct_with_json_name is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["StructWithJsonName"], + self.struct_with_json_name, + ) + + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Timestamp"], + self.timestamp, + ) + + if self.unix_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["UnixTimestamp"], + self.unix_timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["blob"] = de.read_blob( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Blob"] + ) + + case 1: + kwargs["boolean"] = de.read_boolean( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Boolean"] + ) + + case 2: + kwargs["double"] = de.read_double( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Double"] + ) + + case 3: + kwargs["empty_struct"] = EmptyStruct.deserialize(de) + + case 4: + kwargs["float_"] = de.read_float( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Float"] + ) + + case 5: + kwargs["httpdate_timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members[ + "HttpdateTimestamp" + ] + ) + + case 6: + kwargs["integer"] = de.read_integer( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Integer"] + ) + + case 7: + kwargs["iso8601_timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Iso8601Timestamp"] + ) + + case 8: + kwargs["json_value"] = de.read_string( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["JsonValue"] + ) + + case 9: + kwargs["list_of_lists"] = _deserialize_list_of_list_of_strings( + de, _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["ListOfLists"] + ) + + case 10: + kwargs["list_of_maps_of_strings"] = ( + _deserialize_list_of_maps_of_strings( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members[ + "ListOfMapsOfStrings" + ], + ) + ) + + case 11: + kwargs["list_of_strings"] = _deserialize_list_of_strings( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["ListOfStrings"], + ) + + case 12: + kwargs["list_of_structs"] = _deserialize_list_of_structs( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["ListOfStructs"], + ) + + case 13: + kwargs["long"] = de.read_long( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Long"] + ) + + case 14: + kwargs["map_of_lists_of_strings"] = ( + _deserialize_map_of_lists_of_strings( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members[ + "MapOfListsOfStrings" + ], + ) + ) + + case 15: + kwargs["map_of_maps"] = _deserialize_map_of_map_of_strings( + de, _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["MapOfMaps"] + ) + + case 16: + kwargs["map_of_strings"] = _deserialize_map_of_strings( + de, _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["MapOfStrings"] + ) + + case 17: + kwargs["map_of_structs"] = _deserialize_map_of_structs( + de, _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["MapOfStructs"] + ) + + case 18: + kwargs["recursive_list"] = _deserialize_list_of_kitchen_sinks( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["RecursiveList"], + ) + + case 19: + kwargs["recursive_map"] = _deserialize_map_of_kitchen_sinks( + de, _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["RecursiveMap"] + ) + + case 20: + kwargs["recursive_struct"] = KitchenSink.deserialize(de) + + case 21: + kwargs["simple_struct"] = SimpleStruct.deserialize(de) + + case 22: + kwargs["string"] = de.read_string( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["String"] + ) + + case 23: + kwargs["struct_with_json_name"] = StructWithJsonName.deserialize(de) + + case 24: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["Timestamp"] + ) + + case 25: + kwargs["unix_timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT.members["UnixTimestamp"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class KitchenSinkOperationOutput: + """Dataclass for KitchenSinkOperationOutput structure.""" + + blob: bytes | None = None + + boolean: bool | None = None + + double: float | None = None + + empty_struct: EmptyStruct | None = None + + float_: float | None = None + + httpdate_timestamp: datetime | None = None + + integer: int | None = None + + iso8601_timestamp: datetime | None = None + + json_value: str | JsonString | None = None + + list_of_lists: list[list[str]] | None = None + + list_of_maps_of_strings: list[dict[str, str]] | None = None + + list_of_strings: list[str] | None = None + + list_of_structs: list[SimpleStruct] | None = None + + long: int | None = None + + map_of_lists_of_strings: dict[str, list[str]] | None = None + + map_of_maps: dict[str, dict[str, str]] | None = None + + map_of_strings: dict[str, str] | None = None + + map_of_structs: dict[str, SimpleStruct] | None = None + + recursive_list: "list[KitchenSink] | None" = None + + recursive_map: "dict[str, KitchenSink] | None" = None + + recursive_struct: "KitchenSink | None" = None + + simple_struct: SimpleStruct | None = None + + string: str | None = None + + struct_with_json_name: StructWithJsonName | None = None + + timestamp: datetime | None = None + + unix_timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.blob is not None: + serializer.write_blob( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Blob"], self.blob + ) + + if self.boolean is not None: + serializer.write_boolean( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Boolean"], self.boolean + ) + + if self.double is not None: + serializer.write_double( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Double"], self.double + ) + + if self.empty_struct is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["EmptyStruct"], + self.empty_struct, + ) + + if self.float_ is not None: + serializer.write_float( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Float"], self.float_ + ) + + if self.httpdate_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["HttpdateTimestamp"], + self.httpdate_timestamp, + ) + + if self.integer is not None: + serializer.write_integer( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Integer"], self.integer + ) + + if self.iso8601_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Iso8601Timestamp"], + self.iso8601_timestamp, + ) + + if self.json_value is not None: + serializer.write_string( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["JsonValue"], + self.json_value, + ) + + if self.list_of_lists is not None: + _serialize_list_of_list_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["ListOfLists"], + self.list_of_lists, + ) + + if self.list_of_maps_of_strings is not None: + _serialize_list_of_maps_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["ListOfMapsOfStrings"], + self.list_of_maps_of_strings, + ) + + if self.list_of_strings is not None: + _serialize_list_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["ListOfStrings"], + self.list_of_strings, + ) + + if self.list_of_structs is not None: + _serialize_list_of_structs( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["ListOfStructs"], + self.list_of_structs, + ) + + if self.long is not None: + serializer.write_long( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Long"], self.long + ) + + if self.map_of_lists_of_strings is not None: + _serialize_map_of_lists_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["MapOfListsOfStrings"], + self.map_of_lists_of_strings, + ) + + if self.map_of_maps is not None: + _serialize_map_of_map_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["MapOfMaps"], + self.map_of_maps, + ) + + if self.map_of_strings is not None: + _serialize_map_of_strings( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["MapOfStrings"], + self.map_of_strings, + ) + + if self.map_of_structs is not None: + _serialize_map_of_structs( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["MapOfStructs"], + self.map_of_structs, + ) + + if self.recursive_list is not None: + _serialize_list_of_kitchen_sinks( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["RecursiveList"], + self.recursive_list, + ) + + if self.recursive_map is not None: + _serialize_map_of_kitchen_sinks( + serializer, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["RecursiveMap"], + self.recursive_map, + ) + + if self.recursive_struct is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["RecursiveStruct"], + self.recursive_struct, + ) + + if self.simple_struct is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["SimpleStruct"], + self.simple_struct, + ) + + if self.string is not None: + serializer.write_string( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["String"], self.string + ) + + if self.struct_with_json_name is not None: + serializer.write_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["StructWithJsonName"], + self.struct_with_json_name, + ) + + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Timestamp"], + self.timestamp, + ) + + if self.unix_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["UnixTimestamp"], + self.unix_timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["blob"] = de.read_blob( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Blob"] + ) + + case 1: + kwargs["boolean"] = de.read_boolean( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Boolean"] + ) + + case 2: + kwargs["double"] = de.read_double( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Double"] + ) + + case 3: + kwargs["empty_struct"] = EmptyStruct.deserialize(de) + + case 4: + kwargs["float_"] = de.read_float( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Float"] + ) + + case 5: + kwargs["httpdate_timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members[ + "HttpdateTimestamp" + ] + ) + + case 6: + kwargs["integer"] = de.read_integer( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Integer"] + ) + + case 7: + kwargs["iso8601_timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members[ + "Iso8601Timestamp" + ] + ) + + case 8: + kwargs["json_value"] = de.read_string( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["JsonValue"] + ) + + case 9: + kwargs["list_of_lists"] = _deserialize_list_of_list_of_strings( + de, _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["ListOfLists"] + ) + + case 10: + kwargs["list_of_maps_of_strings"] = ( + _deserialize_list_of_maps_of_strings( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members[ + "ListOfMapsOfStrings" + ], + ) + ) + + case 11: + kwargs["list_of_strings"] = _deserialize_list_of_strings( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["ListOfStrings"], + ) + + case 12: + kwargs["list_of_structs"] = _deserialize_list_of_structs( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["ListOfStructs"], + ) + + case 13: + kwargs["long"] = de.read_long( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Long"] + ) + + case 14: + kwargs["map_of_lists_of_strings"] = ( + _deserialize_map_of_lists_of_strings( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members[ + "MapOfListsOfStrings" + ], + ) + ) + + case 15: + kwargs["map_of_maps"] = _deserialize_map_of_map_of_strings( + de, _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["MapOfMaps"] + ) + + case 16: + kwargs["map_of_strings"] = _deserialize_map_of_strings( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["MapOfStrings"], + ) + + case 17: + kwargs["map_of_structs"] = _deserialize_map_of_structs( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["MapOfStructs"], + ) + + case 18: + kwargs["recursive_list"] = _deserialize_list_of_kitchen_sinks( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["RecursiveList"], + ) + + case 19: + kwargs["recursive_map"] = _deserialize_map_of_kitchen_sinks( + de, + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["RecursiveMap"], + ) + + case 20: + kwargs["recursive_struct"] = KitchenSink.deserialize(de) + + case 21: + kwargs["simple_struct"] = SimpleStruct.deserialize(de) + + case 22: + kwargs["string"] = de.read_string( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["String"] + ) + + case 23: + kwargs["struct_with_json_name"] = StructWithJsonName.deserialize(de) + + case 24: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["Timestamp"] + ) + + case 25: + kwargs["unix_timestamp"] = de.read_timestamp( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT.members["UnixTimestamp"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +KITCHEN_SINK_OPERATION = APIOperation( + input=KitchenSinkOperationInput, + output=KitchenSinkOperationOutput, + schema=_SCHEMA_KITCHEN_SINK_OPERATION, + input_schema=_SCHEMA_KITCHEN_SINK_OPERATION_INPUT, + output_schema=_SCHEMA_KITCHEN_SINK_OPERATION_OUTPUT, + error_registry=TypeRegistry( + { + ShapeID("aws.protocoltests.json#ErrorWithMembers"): ErrorWithMembers, + ShapeID("aws.protocoltests.json#ErrorWithoutMembers"): ErrorWithoutMembers, + } + ), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[_SCHEMA_ERROR_WITH_MEMBERS, _SCHEMA_ERROR_WITHOUT_MEMBERS], +) diff --git a/codegen-output/aws-json-1-1/src/awsjson11/user_agent.py b/codegen-output/aws-json-1-1/src/awsjson11/user_agent.py new file mode 100644 index 000000000..9ca581de7 --- /dev/null +++ b/codegen-output/aws-json-1-1/src/awsjson11/user_agent.py @@ -0,0 +1,17 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from smithy_aws_core.interceptors.user_agent import UserAgentInterceptor + +from . import __version__ +from .config import AsyncJsonProtocolConfig + + +def aws_user_agent_plugin(config: AsyncJsonProtocolConfig): + config.interceptors.append( + UserAgentInterceptor( + ua_suffix=config.user_agent_extra, + ua_app_id=config.sdk_ua_app_id, + sdk_version=__version__, + service_id="Json_Protocol", + ) + ) diff --git a/codegen-output/aws-json-1-1/tests/__init__.py b/codegen-output/aws-json-1-1/tests/__init__.py new file mode 100644 index 000000000..247be3e3d --- /dev/null +++ b/codegen-output/aws-json-1-1/tests/__init__.py @@ -0,0 +1 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. diff --git a/codegen-output/aws-json-1-1/tests/test_awsjson11_protocol.py b/codegen-output/aws-json-1-1/tests/test_awsjson11_protocol.py new file mode 100644 index 000000000..0e40b5864 --- /dev/null +++ b/codegen-output/aws-json-1-1/tests/test_awsjson11_protocol.py @@ -0,0 +1,6515 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from datetime import datetime, timezone +import json +from urllib.parse import parse_qsl + +from pytest import fail, mark, raises +from smithy_aws_core.identity import StaticCredentialsResolver +from smithy_core.aio.retries import SimpleRetryStrategy +from smithy_core.aio.types import AsyncBytesReader +from smithy_core.aio.utils import async_list +from smithy_core.documents import Document +from smithy_http import tuples_to_fields +from smithy_http.aio import HTTPResponse as _smithy_http_aio_HTTPResponse +from smithy_http.aio.interfaces import ( + HTTPRequest, + HTTPResponse as _smithy_http_aio_interfaces_HTTPResponse, +) +from smithy_http.interfaces import HTTPClientConfiguration, HTTPRequestConfiguration + +from awsjson11.client import AsyncJsonProtocolClient +from awsjson11.config import AsyncJsonProtocolConfig +from awsjson11.models import ( + DatetimeOffsetsInput, + DatetimeOffsetsOutput, + EmptyOperationInput, + EmptyOperationOutput, + EmptyStruct, + EndpointOperationInput, + EndpointWithHostLabelOperationInput, + FractionalSecondsInput, + FractionalSecondsOutput, + GreetingStruct, + GreetingWithErrorsInput, + HostWithPathOperationInput, + JsonEnumsInput, + JsonEnumsOutput, + JsonIntEnumsInput, + JsonIntEnumsOutput, + JsonUnionsInput, + JsonUnionsOutput, + KitchenSink, + KitchenSinkOperationInput, + KitchenSinkOperationOutput, + MyUnionBlobValue, + MyUnionBooleanValue, + MyUnionEnumValue, + MyUnionListValue, + MyUnionMapValue, + MyUnionNumberValue, + MyUnionStringValue, + MyUnionStructureValue, + MyUnionTimestampValue, + NullOperationInput, + NullOperationOutput, + OperationWithOptionalInputOutputInput, + PutAndGetInlineDocumentsInput, + PutAndGetInlineDocumentsOutput, + PutWithContentEncodingInput, + ServiceError, + SimpleScalarPropertiesInput, + SimpleScalarPropertiesOutput, + SimpleStruct, + SparseNullsOperationInput, + SparseNullsOperationOutput, + StructWithJsonName, +) + + +async def test_aws_json11_date_time_with_negative_offset_response_datetime_offsets() -> ( + None +): + """ + Ensures that clients can correctly parse datetime (timestamps) with + offsets + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b' {\n "datetime": "2019-12-16T22:48:18-01:00"\n }\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DatetimeOffsetsInput() + + try: + actual = await client.datetime_offsets(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DatetimeOffsetsOutput( + datetime_=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_aws_json11_date_time_with_positive_offset_response_datetime_offsets() -> ( + None +): + """ + Ensures that clients can correctly parse datetime (timestamps) with + offsets + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b' {\n "datetime": "2019-12-17T00:48:18+01:00"\n }\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DatetimeOffsetsInput() + + try: + actual = await client.datetime_offsets(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DatetimeOffsetsOutput( + datetime_=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_sends_requests_to_slash_request_empty_operation() -> None: + """Sends requests to /""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyOperationInput() + + try: + await client.empty_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.EmptyOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_includes_x_amz_target_and_content_type_request_empty_operation() -> None: + """Includes X-Amz-Target header and Content-Type""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyOperationInput() + + try: + await client.empty_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.EmptyOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_json_1_1_client_sends_empty_payload_for_no_input_shape_request_empty_operation() -> ( + None +): + """ + Clients must always send an empty JSON object payload for operations + with no input (that is, `{}`). While AWS service implementations + support requests with no payload or requests that send `{}`, always + sending `{}` from the client is preferred for forward compatibility in + case input is ever added to an operation. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyOperationInput() + + try: + await client.empty_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.EmptyOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_handles_empty_output_shape_response_empty_operation() -> None: + """ + When no output is defined, the service is expected to return an empty + payload, however, client must ignore a JSON payload if one is returned. + This ensures that if output is added later, then it will not break the + client. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyOperationInput() + + try: + actual = await client.empty_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = EmptyOperationOutput() + + assert actual == expected + + +async def test_handles_unexpected_json_output_response_empty_operation() -> None: + """ + This client-only test builds on handles_empty_output_shape, by including + unexpected fields in the JSON. A client needs to ignore JSON output that + is empty or that contains JSON object data. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "foo": true\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyOperationInput() + + try: + actual = await client.empty_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = EmptyOperationOutput() + + assert actual == expected + + +async def test_json_1_1_service_responds_with_no_payload_response_empty_operation() -> ( + None +): + """ + When no output is defined, the service is expected to return an empty + payload. Despite the lack of a payload, the service is expected to + always send a Content-Type header. Clients must handle cases where a + service returns a JSON object and where a service returns no JSON at + all. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyOperationInput() + + try: + actual = await client.empty_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = EmptyOperationOutput() + + assert actual == expected + + +@mark.xfail() +async def test_aws_json11_endpoint_trait_request_endpoint_operation() -> None: + """ + Operations can prepend to the given host if they define the endpoint + trait. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EndpointOperationInput() + + try: + await client.endpoint_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "foo.example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.EndpointOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_json11_endpoint_trait_with_host_label_request_endpoint_with_host_label_operation() -> ( + None +): + """ + Operations can prepend to the given host if they define the endpoint + trait, and can use the host label trait to define further customization + based on user input. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EndpointWithHostLabelOperationInput(label="bar") + + try: + await client.endpoint_with_host_label_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "foo.bar.example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.EndpointWithHostLabelOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"label": "bar"}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_date_time_with_fractional_seconds_response_fractional_seconds() -> ( + None +): + """ + Ensures that clients can correctly parse datetime timestamps with + fractional seconds + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b' {\n "datetime": "2000-01-02T20:34:56.123Z"\n }\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = FractionalSecondsInput() + + try: + actual = await client.fractional_seconds(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = FractionalSecondsOutput( + datetime_=datetime(2000, 1, 2, 20, 34, 56, 123000, timezone.utc) + ) + + assert actual == expected + + +async def test_aws_json11_invalid_greeting_error_error_greeting_with_errors() -> None: + """Parses simple JSON errors""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=400, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "__type": "InvalidGreeting",\n "Message": "Hi"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'InvalidGreeting' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "InvalidGreeting": + fail( + f"Expected 'InvalidGreeting' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_complex_error_error_greeting_with_errors() -> None: + """Parses a complex error with no message member""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=400, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "__type": "ComplexError",\n "TopLevel": "Top level",\n "Nested": {\n "Foo": "bar"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'ComplexError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "ComplexError": + fail( + f"Expected 'ComplexError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_empty_complex_error_error_greeting_with_errors() -> None: + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=400, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "__type": "ComplexError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'ComplexError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "ComplexError": + fail( + f"Expected 'ComplexError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_using_x_amzn_error_type_error_greeting_with_errors() -> ( + None +): + """ + Serializes the X-Amzn-ErrorType header. For an example service, see + Amazon EKS. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, headers=[("X-Amzn-Errortype", "FooError")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_using_x_amzn_error_type_with_uri_error_greeting_with_errors() -> ( + None +): + """ + Some X-Amzn-Errortype headers contain URLs. Clients need to split the + URL on ':' and take only the first half of the string. For example, + 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/' + is to be interpreted as 'ValidationException'. For an example service + see Amazon Polly. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[ + ( + "X-Amzn-Errortype", + "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/", + ) + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_using_x_amzn_error_type_with_uri_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + X-Amzn-Errortype might contain a URL and a namespace. Client should + extract only the shape name. This is a pathalogical case that might not + actually happen in any deployed AWS service. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[ + ( + "X-Amzn-Errortype", + "aws.protocoltests.json#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/", + ) + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_using_code_error_greeting_with_errors() -> None: + """ + This example uses the 'code' property in the output rather than + X-Amzn-Errortype. Some services do this though it's preferable to send + the X-Amzn-Errortype. Client implementations must first check for the + X-Amzn-Errortype and then check for a top-level 'code' property. For + example service see Amazon S3 Glacier. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "code": "FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_using_code_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using code, and it might contain a + namespace. Clients should just take the last part of the string after + '#'. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "code": "aws.protocoltests.json#FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_using_code_uri_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using code, and it might contain a + namespace. It also might contain a URI. Clients should just take the + last part of the string after '#' and before \":\". This is a + pathalogical case that might not occur in any deployed AWS service. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "code": "aws.protocoltests.json#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_with_dunder_type_error_greeting_with_errors() -> ( + None +): + """Some services serialize errors using __type.""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "__type": "FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_with_dunder_type_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using __type, and it might contain a + namespace. Clients should just take the last part of the string after + '#'. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "__type": "aws.protocoltests.json#FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_with_dunder_type_and_different_namespace_error_greeting_with_errors() -> ( + None +): + """ + Because only the part after '#' is considered, an unrecognized + namespace should not make a difference. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "__type": "aws.different.namespace#FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_with_dunder_type_uri_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using __type, and it might contain a + namespace. It also might contain a URI. Clients should just take the + last part of the string after '#' and before \":\". This is a + pathalogical case that might not occur in any deployed AWS service. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "__type": "aws.protocoltests.json#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_foo_error_with_nested_type_property_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using __type, and if the response + includes additional shapes that belong to a different namespace + there'll be a nested __type property that must not be considered when + determining which error to be surfaced. For an example service see + Amazon DynamoDB. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "__type": "aws.protocoltests.json#FooError",\n "ErrorDetails": [\n {\n "__type": "com.amazon.internal#ErrorDetails",\n "reason": "Some reason"\n }\n ]\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_host_with_path_request_host_with_path_operation() -> None: + """Custom endpoints supplied by users can have paths""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/custom", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HostWithPathOperationInput() + + try: + await client.host_with_path_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/custom/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.HostWithPathOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_enums_request_json_enums() -> None: + """Serializes simple scalar properties""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonEnumsInput( + foo_enum1="Foo", + foo_enum2="0", + foo_enum3="1", + foo_enum_list=["Foo", "0"], + foo_enum_set=["Foo", "0"], + foo_enum_map={"hi": "Foo", "zero": "0"}, + ) + + try: + await client.json_enums(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonEnums"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "fooEnum1": "Foo",\n "fooEnum2": "0",\n "fooEnum3": "1",\n "fooEnumList": [\n "Foo",\n "0"\n ],\n "fooEnumSet": [\n "Foo",\n "0"\n ],\n "fooEnumMap": {\n "hi": "Foo",\n "zero": "0"\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_enums_response_json_enums() -> None: + """Serializes simple scalar properties""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "fooEnum1": "Foo",\n "fooEnum2": "0",\n "fooEnum3": "1",\n "fooEnumList": [\n "Foo",\n "0"\n ],\n "fooEnumSet": [\n "Foo",\n "0"\n ],\n "fooEnumMap": {\n "hi": "Foo",\n "zero": "0"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonEnumsInput() + + try: + actual = await client.json_enums(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonEnumsOutput( + foo_enum1="Foo", + foo_enum2="0", + foo_enum3="1", + foo_enum_list=["Foo", "0"], + foo_enum_set=["Foo", "0"], + foo_enum_map={"hi": "Foo", "zero": "0"}, + ) + + assert actual == expected + + +async def test_aws_json11_int_enums_request_json_int_enums() -> None: + """Serializes simple scalar properties""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonIntEnumsInput( + int_enum1=1, + int_enum2=2, + int_enum3=3, + int_enum_list=[1, 2], + int_enum_set=[1, 2], + int_enum_map={"a": 1, "b": 2}, + ) + + try: + await client.json_int_enums(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonIntEnums"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "intEnum1": 1,\n "intEnum2": 2,\n "intEnum3": 3,\n "intEnumList": [\n 1,\n 2\n ],\n "intEnumSet": [\n 1,\n 2\n ],\n "intEnumMap": {\n "a": 1,\n "b": 2\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_int_enums_response_json_int_enums() -> None: + """Serializes simple scalar properties""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[ + ("Content-Type", "application/x-amz-json-1.1"), + ("X-Amz-Target", "JsonProtocol.JsonIntEnums"), + ], + body=b'{\n "intEnum1": 1,\n "intEnum2": 2,\n "intEnum3": 3,\n "intEnumList": [\n 1,\n 2\n ],\n "intEnumSet": [\n 1,\n 2\n ],\n "intEnumMap": {\n "a": 1,\n "b": 2\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonIntEnumsInput() + + try: + actual = await client.json_int_enums(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonIntEnumsOutput( + int_enum1=1, + int_enum2=2, + int_enum3=3, + int_enum_list=[1, 2], + int_enum_set=[1, 2], + int_enum_map={"a": 1, "b": 2}, + ) + + assert actual == expected + + +async def test_aws_json11_serialize_string_union_value_request_json_unions() -> None: + """Serializes a string union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionStringValue(value="foo")) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "stringValue": "foo"\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_serialize_boolean_union_value_request_json_unions() -> None: + """Serializes a boolean union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionBooleanValue(value=True)) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "booleanValue": true\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_serialize_number_union_value_request_json_unions() -> None: + """Serializes a number union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionNumberValue(value=1)) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "numberValue": 1\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_serialize_blob_union_value_request_json_unions() -> None: + """Serializes a blob union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionBlobValue(value=b"foo")) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "blobValue": "Zm9v"\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_serialize_timestamp_union_value_request_json_unions() -> None: + """Serializes a timestamp union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionTimestampValue( + value=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "timestampValue": 1398796238\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_serialize_enum_union_value_request_json_unions() -> None: + """Serializes an enum union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionEnumValue(value="Foo")) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "enumValue": "Foo"\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_serialize_list_union_value_request_json_unions() -> None: + """Serializes a list union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionListValue(value=["foo", "bar"])) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_serialize_map_union_value_request_json_unions() -> None: + """Serializes a map union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionMapValue(value={"foo": "bar", "spam": "eggs"}) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_serialize_structure_union_value_request_json_unions() -> None: + """Serializes a structure union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.JsonUnions"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_deserialize_string_union_value_response_json_unions() -> None: + """Deserializes a string union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "stringValue": "foo"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionStringValue(value="foo")) + + assert actual == expected + + +async def test_aws_json11_deserialize_boolean_union_value_response_json_unions() -> ( + None +): + """Deserializes a boolean union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "booleanValue": true\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionBooleanValue(value=True)) + + assert actual == expected + + +async def test_aws_json11_deserialize_number_union_value_response_json_unions() -> None: + """Deserializes a number union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "numberValue": 1\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionNumberValue(value=1)) + + assert actual == expected + + +async def test_aws_json11_deserialize_blob_union_value_response_json_unions() -> None: + """Deserializes a blob union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "blobValue": "Zm9v"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionBlobValue(value=b"foo")) + + assert actual == expected + + +async def test_aws_json11_deserialize_timestamp_union_value_response_json_unions() -> ( + None +): + """Deserializes a timestamp union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "timestampValue": 1398796238\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionTimestampValue( + value=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + ) + + assert actual == expected + + +async def test_aws_json11_deserialize_enum_union_value_response_json_unions() -> None: + """Deserializes an enum union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "enumValue": "Foo"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionEnumValue(value="Foo")) + + assert actual == expected + + +async def test_aws_json11_deserialize_list_union_value_response_json_unions() -> None: + """Deserializes a list union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionListValue(value=["foo", "bar"])) + + assert actual == expected + + +async def test_aws_json11_deserialize_map_union_value_response_json_unions() -> None: + """Deserializes a map union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionMapValue(value={"foo": "bar", "spam": "eggs"}) + ) + + assert actual == expected + + +async def test_aws_json11_deserialize_structure_union_value_response_json_unions() -> ( + None +): + """Deserializes a structure union value""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + assert actual == expected + + +async def test_aws_json11_deserialize_ignore_type_response_json_unions() -> None: + """Ignores an unrecognized __type property""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "contents": {\n "__type": "aws.protocoltests.json10#MyUnion",\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + assert actual == expected + + +async def test_serializes_string_shapes_request_kitchen_sink_operation() -> None: + """Serializes string shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(string="abc xyz") + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"String":"abc xyz"}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_string_shapes_with_jsonvalue_trait_request_kitchen_sink_operation() -> ( + None +): + """Serializes string shapes with jsonvalue trait""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + json_value='{"string":"value","number":1234.5,"boolTrue":true,"boolFalse":false,"array":[1,2,3,4],"object":{"key":"value"},"null":null}' + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"JsonValue":"{\\"string\\":\\"value\\",\\"number\\":1234.5,\\"boolTrue\\":true,\\"boolFalse\\":false,\\"array\\":[1,2,3,4],\\"object\\":{\\"key\\":\\"value\\"},\\"null\\":null}"}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_integer_shapes_request_kitchen_sink_operation() -> None: + """Serializes integer shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(integer=1234) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Integer":1234}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_long_shapes_request_kitchen_sink_operation() -> None: + """Serializes long shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(long=999999999999) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Long":999999999999}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_float_shapes_request_kitchen_sink_operation() -> None: + """Serializes float shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(float_=float(1234.5)) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Float":1234.5}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_double_shapes_request_kitchen_sink_operation() -> None: + """Serializes double shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(double=float(1234.5)) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Double":1234.5}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_blob_shapes_request_kitchen_sink_operation() -> None: + """Serializes blob shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(blob=b"binary-value") + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Blob":"YmluYXJ5LXZhbHVl"}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_boolean_shapes_true_request_kitchen_sink_operation() -> None: + """Serializes boolean shapes (true)""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(boolean=True) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Boolean":true}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_boolean_shapes_false_request_kitchen_sink_operation() -> None: + """Serializes boolean shapes (false)""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(boolean=False) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Boolean":false}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_timestamp_shapes_request_kitchen_sink_operation() -> None: + """Serializes timestamp shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + timestamp=datetime(2000, 1, 2, 20, 34, 56, 0, timezone.utc) + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Timestamp":946845296}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_timestamp_shapes_with_iso8601_timestampformat_request_kitchen_sink_operation() -> ( + None +): + """Serializes timestamp shapes with iso8601 timestampFormat""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + iso8601_timestamp=datetime(2000, 1, 2, 20, 34, 56, 0, timezone.utc) + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Iso8601Timestamp":"2000-01-02T20:34:56Z"}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_timestamp_shapes_with_httpdate_timestampformat_request_kitchen_sink_operation() -> ( + None +): + """Serializes timestamp shapes with httpdate timestampFormat""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + httpdate_timestamp=datetime(2000, 1, 2, 20, 34, 56, 0, timezone.utc) + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"HttpdateTimestamp":"Sun, 02 Jan 2000 20:34:56 GMT"}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_timestamp_shapes_with_unixtimestamp_timestampformat_request_kitchen_sink_operation() -> ( + None +): + """Serializes timestamp shapes with unixTimestamp timestampFormat""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + unix_timestamp=datetime(2000, 1, 2, 20, 34, 56, 0, timezone.utc) + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"UnixTimestamp":946845296}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_list_shapes_request_kitchen_sink_operation() -> None: + """Serializes list shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(list_of_strings=["abc", "mno", "xyz"]) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"ListOfStrings":["abc","mno","xyz"]}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_empty_list_shapes_request_kitchen_sink_operation() -> None: + """Serializes empty list shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(list_of_strings=[]) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"ListOfStrings":[]}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_list_of_map_shapes_request_kitchen_sink_operation() -> None: + """Serializes list of map shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + list_of_maps_of_strings=[{"foo": "bar"}, {"abc": "xyz"}, {"red": "blue"}] + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{"ListOfMapsOfStrings":[{"foo":"bar"},{"abc":"xyz"},{"red":"blue"}]}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_list_of_structure_shapes_request_kitchen_sink_operation() -> ( + None +): + """Serializes list of structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + list_of_structs=[ + SimpleStruct(value="abc"), + SimpleStruct(value="mno"), + SimpleStruct(value="xyz"), + ] + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{"ListOfStructs":[{"Value":"abc"},{"Value":"mno"},{"Value":"xyz"}]}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_list_of_recursive_structure_shapes_request_kitchen_sink_operation() -> ( + None +): + """Serializes list of recursive structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + recursive_list=[ + KitchenSink( + recursive_list=[KitchenSink(recursive_list=[KitchenSink(integer=123)])] + ) + ] + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"RecursiveList":[{"RecursiveList":[{"RecursiveList":[{"Integer":123}]}]}]}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_map_shapes_request_kitchen_sink_operation() -> None: + """Serializes map shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(map_of_strings={"abc": "xyz", "mno": "hjk"}) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"MapOfStrings":{"abc":"xyz","mno":"hjk"}}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_empty_map_shapes_request_kitchen_sink_operation() -> None: + """Serializes empty map shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(map_of_strings={}) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"MapOfStrings":{}}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_map_of_list_shapes_request_kitchen_sink_operation() -> None: + """Serializes map of list shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + map_of_lists_of_strings={"abc": ["abc", "xyz"], "mno": ["xyz", "abc"]} + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{"MapOfListsOfStrings":{"abc":["abc","xyz"],"mno":["xyz","abc"]}}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_map_of_structure_shapes_request_kitchen_sink_operation() -> ( + None +): + """Serializes map of structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + map_of_structs={ + "key1": SimpleStruct(value="value-1"), + "key2": SimpleStruct(value="value-2"), + } + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{"MapOfStructs":{"key1":{"Value":"value-1"},"key2":{"Value":"value-2"}}}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_map_of_recursive_structure_shapes_request_kitchen_sink_operation() -> ( + None +): + """Serializes map of recursive structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + recursive_map={ + "key1": KitchenSink( + recursive_map={ + "key2": KitchenSink( + recursive_map={"key3": KitchenSink(boolean=False)} + ) + } + ) + } + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"RecursiveMap":{"key1":{"RecursiveMap":{"key2":{"RecursiveMap":{"key3":{"Boolean":false}}}}}}}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_structure_shapes_request_kitchen_sink_operation() -> None: + """Serializes structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(simple_struct=SimpleStruct(value="abc")) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"SimpleStruct":{"Value":"abc"}}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_structure_members_with_locationname_traits_request_kitchen_sink_operation() -> ( + None +): + """Serializes structure members with locationName traits""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + struct_with_json_name=StructWithJsonName(value="some-value") + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"StructWithJsonName":{"Value":"some-value"}}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_empty_structure_shapes_request_kitchen_sink_operation() -> ( + None +): + """Serializes empty structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(simple_struct=SimpleStruct()) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"SimpleStruct":{}}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_structure_which_have_no_members_request_kitchen_sink_operation() -> ( + None +): + """Serializes structure which have no members""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput(empty_struct=EmptyStruct()) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"EmptyStruct":{}}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_serializes_recursive_structure_shapes_request_kitchen_sink_operation() -> ( + None +): + """Serializes recursive structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput( + boolean=False, + recursive_struct=KitchenSink( + boolean=True, + recursive_list=[ + KitchenSink(string="string-only"), + KitchenSink( + recursive_struct=KitchenSink( + map_of_strings={"color": "red", "size": "large"} + ) + ), + ], + string="nested-value", + ), + string="top-value", + ) + + try: + await client.kitchen_sink_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.KitchenSinkOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"String":"top-value","Boolean":false,"RecursiveStruct":{"String":"nested-value","Boolean":true,"RecursiveList":[{"String":"string-only"},{"RecursiveStruct":{"MapOfStrings":{"color":"red","size":"large"}}}]}}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_parses_operations_with_empty_json_bodies_response_kitchen_sink_operation() -> ( + None +): + """Parses operations with empty JSON bodies""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput() + + assert actual == expected + + +async def test_parses_string_shapes_response_kitchen_sink_operation() -> None: + """Parses string shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"String":"string-value"}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput(string="string-value") + + assert actual == expected + + +async def test_parses_integer_shapes_response_kitchen_sink_operation() -> None: + """Parses integer shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"Integer":1234}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput(integer=1234) + + assert actual == expected + + +async def test_parses_long_shapes_response_kitchen_sink_operation() -> None: + """Parses long shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"Long":1234567890123456789}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput(long=1234567890123456789) + + assert actual == expected + + +async def test_parses_float_shapes_response_kitchen_sink_operation() -> None: + """Parses float shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"Float":1234.5}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput(float_=float(1234.5)) + + assert actual == expected + + +async def test_parses_double_shapes_response_kitchen_sink_operation() -> None: + """Parses double shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"Double":123456789.12345679}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput(double=float(1.2345678912345679e8)) + + assert actual == expected + + +async def test_parses_boolean_shapes_true_response_kitchen_sink_operation() -> None: + """Parses boolean shapes (true)""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"Boolean":true}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput(boolean=True) + + assert actual == expected + + +async def test_parses_boolean_false_response_kitchen_sink_operation() -> None: + """Parses boolean (false)""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"Boolean":false}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput(boolean=False) + + assert actual == expected + + +async def test_parses_blob_shapes_response_kitchen_sink_operation() -> None: + """Parses blob shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"Blob":"YmluYXJ5LXZhbHVl"}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput(blob=b"binary-value") + + assert actual == expected + + +async def test_parses_timestamp_shapes_response_kitchen_sink_operation() -> None: + """Parses timestamp shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"Timestamp":946845296}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + timestamp=datetime(2000, 1, 2, 20, 34, 56, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_parses_iso8601_timestamps_response_kitchen_sink_operation() -> None: + """Parses iso8601 timestamps""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"Iso8601Timestamp":"2000-01-02T20:34:56Z"}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + iso8601_timestamp=datetime(2000, 1, 2, 20, 34, 56, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_parses_httpdate_timestamps_response_kitchen_sink_operation() -> None: + """Parses httpdate timestamps""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"HttpdateTimestamp":"Sun, 02 Jan 2000 20:34:56 GMT"}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + httpdate_timestamp=datetime(2000, 1, 2, 20, 34, 56, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_parses_list_shapes_response_kitchen_sink_operation() -> None: + """Parses list shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"ListOfStrings":["abc","mno","xyz"]}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput(list_of_strings=["abc", "mno", "xyz"]) + + assert actual == expected + + +async def test_parses_list_of_map_shapes_response_kitchen_sink_operation() -> None: + """Parses list of map shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"ListOfMapsOfStrings":[{"size":"large"},{"color":"red"}]}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + list_of_maps_of_strings=[{"size": "large"}, {"color": "red"}] + ) + + assert actual == expected + + +async def test_parses_list_of_list_shapes_response_kitchen_sink_operation() -> None: + """Parses list of list shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"ListOfLists":[["abc","mno","xyz"],["hjk","qrs","tuv"]]}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + list_of_lists=[["abc", "mno", "xyz"], ["hjk", "qrs", "tuv"]] + ) + + assert actual == expected + + +async def test_parses_list_of_structure_shapes_response_kitchen_sink_operation() -> ( + None +): + """Parses list of structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"ListOfStructs":[{"Value":"value-1"},{"Value":"value-2"}]}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + list_of_structs=[ + SimpleStruct(value="value-1"), + SimpleStruct(value="value-2"), + ] + ) + + assert actual == expected + + +async def test_parses_list_of_recursive_structure_shapes_response_kitchen_sink_operation() -> ( + None +): + """Parses list of recursive structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"RecursiveList":[{"RecursiveList":[{"RecursiveList":[{"String":"value"}]}]}]}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + recursive_list=[ + KitchenSink( + recursive_list=[ + KitchenSink(recursive_list=[KitchenSink(string="value")]) + ] + ) + ] + ) + + assert actual == expected + + +async def test_parses_map_shapes_response_kitchen_sink_operation() -> None: + """Parses map shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"MapOfStrings":{"size":"large","color":"red"}}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + map_of_strings={"size": "large", "color": "red"} + ) + + assert actual == expected + + +async def test_parses_map_of_list_shapes_response_kitchen_sink_operation() -> None: + """Parses map of list shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"MapOfListsOfStrings":{"sizes":["large","small"],"colors":["red","green"]}}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + map_of_lists_of_strings={ + "sizes": ["large", "small"], + "colors": ["red", "green"], + } + ) + + assert actual == expected + + +async def test_parses_map_of_map_shapes_response_kitchen_sink_operation() -> None: + """Parses map of map shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"MapOfMaps":{"sizes":{"large":"L","medium":"M"},"colors":{"red":"R","blue":"B"}}}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + map_of_maps={ + "sizes": {"large": "L", "medium": "M"}, + "colors": {"red": "R", "blue": "B"}, + } + ) + + assert actual == expected + + +async def test_parses_map_of_structure_shapes_response_kitchen_sink_operation() -> None: + """Parses map of structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"MapOfStructs":{"size":{"Value":"small"},"color":{"Value":"red"}}}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + map_of_structs={ + "size": SimpleStruct(value="small"), + "color": SimpleStruct(value="red"), + } + ) + + assert actual == expected + + +async def test_parses_map_of_recursive_structure_shapes_response_kitchen_sink_operation() -> ( + None +): + """Parses map of recursive structure shapes""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{"RecursiveMap":{"key-1":{"RecursiveMap":{"key-2":{"RecursiveMap":{"key-3":{"String":"value"}}}}}}}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput( + recursive_map={ + "key-1": KitchenSink( + recursive_map={ + "key-2": KitchenSink( + recursive_map={"key-3": KitchenSink(string="value")} + ) + } + ) + } + ) + + assert actual == expected + + +async def test_parses_the_request_id_from_the_response_response_kitchen_sink_operation() -> ( + None +): + """Parses the request id from the response""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[ + ("Content-Type", "application/x-amz-json-1.1"), + ("X-Amzn-Requestid", "amazon-uniq-request-id"), + ], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = KitchenSinkOperationInput() + + try: + actual = await client.kitchen_sink_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = KitchenSinkOperationOutput() + + assert actual == expected + + +async def test_aws_json11_structures_dont_serialize_null_values_request_null_operation() -> ( + None +): + """Null structure values are dropped""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NullOperationInput(string=None) + + try: + await client.null_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.NullOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_structures_dont_deserialize_null_values_response_null_operation() -> ( + None +): + """Null structure values are dropped""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "string": null\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NullOperationInput() + + try: + actual = await client.null_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NullOperationOutput() + + assert actual == expected + + +async def test_can_call_operation_with_no_input_or_output_request_operation_with_optional_input_output() -> ( + None +): + """Can call operations with no input or output""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithOptionalInputOutputInput() + + try: + await client.operation_with_optional_input_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.OperationWithOptionalInputOutput"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_can_call_operation_with_optional_input_request_operation_with_optional_input_output() -> ( + None +): + """Can invoke operations with optional input""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithOptionalInputOutputInput(value="Hi") + + try: + await client.operation_with_optional_input_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.OperationWithOptionalInputOutput"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"Value":"Hi"}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_put_and_get_inline_documents_input_request_put_and_get_inline_documents() -> ( + None +): + """Serializes inline documents in a JSON request.""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutAndGetInlineDocumentsInput(inline_document=Document({"foo": "bar"})) + + try: + await client.put_and_get_inline_documents(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.PutAndGetInlineDocuments"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "inlineDocument": {"foo": "bar"}\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_put_and_get_inline_documents_input_response_put_and_get_inline_documents() -> ( + None +): + """Serializes inline documents in a JSON response.""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "inlineDocument": {"foo": "bar"}\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutAndGetInlineDocumentsInput() + + try: + actual = await client.put_and_get_inline_documents(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = PutAndGetInlineDocumentsOutput( + inline_document=Document({"foo": "bar"}) + ) + + assert actual == expected + + +@mark.xfail() +async def test_sdk_applied_content_encoding_aws_json1_1_request_put_with_content_encoding() -> ( + None +): + """ + Compression algorithm encoding is appended to the Content-Encoding + header. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutWithContentEncodingInput( + data="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\n" + ) + + try: + await client.put_with_content_encoding(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-encoding", "gzip")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_sdk_appends_gzip_and_ignores_http_provided_encoding_aws_json1_1_request_put_with_content_encoding() -> ( + None +): + """ + Compression algorithm encoding is appended to the Content-Encoding + header, and the user-provided content-encoding is NOT in the + Content-Encoding header since HTTP binding traits are ignored in the + awsJson1_1 protocol. + """ + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutWithContentEncodingInput( + encoding="custom", + data="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\n", + ) + + try: + await client.put_with_content_encoding(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-encoding", "gzip")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_json11_supports_na_n_float_inputs_request_simple_scalar_properties() -> ( + None +): + """Supports handling NaN float values.""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + float_value=float("nan"), double_value=float("nan") + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.SimpleScalarProperties"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "floatValue": "NaN",\n "doubleValue": "NaN"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_supports_infinity_float_inputs_request_simple_scalar_properties() -> ( + None +): + """Supports handling Infinity float values.""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + float_value=float("inf"), double_value=float("inf") + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.SimpleScalarProperties"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "floatValue": "Infinity",\n "doubleValue": "Infinity"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_supports_negative_infinity_float_inputs_request_simple_scalar_properties() -> ( + None +): + """Supports handling -Infinity float values.""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + float_value=float("-inf"), double_value=float("-inf") + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.SimpleScalarProperties"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "floatValue": "-Infinity",\n "doubleValue": "-Infinity"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_json11_supports_na_n_float_inputs_response_simple_scalar_properties() -> ( + None +): + """Supports handling NaN float values.""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "floatValue": "NaN",\n "doubleValue": "NaN"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + float_value=float("nan"), double_value=float("nan") + ) + + assert actual == expected + + +async def test_aws_json11_supports_infinity_float_inputs_response_simple_scalar_properties() -> ( + None +): + """Supports handling Infinity float values.""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "floatValue": "Infinity",\n "doubleValue": "Infinity"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + float_value=float("inf"), double_value=float("inf") + ) + + assert actual == expected + + +async def test_aws_json11_supports_negative_infinity_float_inputs_response_simple_scalar_properties() -> ( + None +): + """Supports handling -Infinity float values.""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "floatValue": "-Infinity",\n "doubleValue": "-Infinity"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + float_value=float("-inf"), double_value=float("-inf") + ) + + assert actual == expected + + +async def test_aws_json11_sparse_maps_serialize_null_values_request_sparse_nulls_operation() -> ( + None +): + """Serializes null values in maps""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseNullsOperationInput(sparse_string_map={"foo": None}) + + try: + await client.sparse_nulls_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.SparseNullsOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "sparseStringMap": {\n "foo": null\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_sparse_lists_serialize_null_request_sparse_nulls_operation() -> ( + None +): + """Serializes null values in lists""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseNullsOperationInput(sparse_string_list=[None]) + + try: + await client.sparse_nulls_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-amz-json-1.1"), + ("x-amz-target", "JsonProtocol.SparseNullsOperation"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "sparseStringList": [\n null\n ]\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_json11_sparse_maps_deserialize_null_values_response_sparse_nulls_operation() -> ( + None +): + """Deserializes null values in maps""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "sparseStringMap": {\n "foo": null\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseNullsOperationInput() + + try: + actual = await client.sparse_nulls_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SparseNullsOperationOutput(sparse_string_map={"foo": None}) + + assert actual == expected + + +async def test_aws_json11_sparse_lists_deserialize_null_response_sparse_nulls_operation() -> ( + None +): + """Deserializes null values in lists""" + client = AsyncJsonProtocolClient( + config=await AsyncJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/x-amz-json-1.1")], + body=b'{\n "sparseStringList": [\n null\n ]\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseNullsOperationInput() + + try: + actual = await client.sparse_nulls_operation(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SparseNullsOperationOutput(sparse_string_list=[None]) + + assert actual == expected + + +class TestHttpServiceError(ServiceError): + """A test error that subclasses the service-error for protocol tests.""" + + def __init__(self, request: HTTPRequest): + self.request = request + + +class RequestTestHTTPClient: + """An asynchronous HTTP client solely for testing purposes.""" + + TIMEOUT_EXCEPTIONS = () + SUPPORTS_DUPLEX_STREAMING: bool = True + + def __init__(self, *, client_config: HTTPClientConfiguration | None = None): + self._client_config = client_config + + async def send( + self, + request: HTTPRequest, + *, + request_config: HTTPRequestConfiguration | None = None, + ) -> _smithy_http_aio_interfaces_HTTPResponse: + # Raise the exception with the request object to bypass actual request handling + raise TestHttpServiceError(request) + + +class ResponseTestHTTPClient: + """An asynchronous HTTP client solely for testing purposes.""" + + TIMEOUT_EXCEPTIONS = () + SUPPORTS_DUPLEX_STREAMING: bool = True + + def __init__( + self, + *, + client_config: HTTPClientConfiguration | None = None, + status: int = 200, + headers: list[tuple[str, str]] | None = None, + body: bytes = b"", + ): + self._client_config = client_config + self.status = status + self.fields = tuples_to_fields(headers or []) + self.body = body + + async def send( + self, + request: HTTPRequest, + *, + request_config: HTTPRequestConfiguration | None = None, + ) -> _smithy_http_aio_HTTPResponse: + # Pre-construct the response from the request and return it + return _smithy_http_aio_HTTPResponse( + status=self.status, fields=self.fields, body=async_list([self.body]) + ) diff --git a/codegen-output/aws-query/README.md b/codegen-output/aws-query/README.md new file mode 100644 index 000000000..fcfa2f6ec --- /dev/null +++ b/codegen-output/aws-query/README.md @@ -0,0 +1,9 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +## Sample Query Protocol Service Client + +awsquery client + +### Documentation + +A query service that sends query requests and XML responses. diff --git a/codegen-output/aws-query/pyproject.toml b/codegen-output/aws-query/pyproject.toml new file mode 100644 index 000000000..ac4dfaa00 --- /dev/null +++ b/codegen-output/aws-query/pyproject.toml @@ -0,0 +1,66 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +[project] +name = "awsquery" +version = "0.0.1" +description = "awsquery client" +readme = "README.md" +requires-python = ">=3.12" +keywords = ["smithy", "awsquery"] +license = {text = "Apache-2.0"} +classifiers = [ + "Development Status :: 2 - Pre-Alpha", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Natural Language :: English", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14" +] + +dependencies = [ + "smithy_aws_core[xml]~=0.11.0", + "smithy_core~=0.8.0", + "smithy_http[aiohttp]~=0.5.0" +] + +[project.optional-dependencies] +awscrt = [ + "smithy_http[awscrt]~=0.5.0" +] + +[dependency-groups] +test = [ + "pytest>=9.0.1,<10.0.0", + "pytest-asyncio>=1.3.0,<1.4.0" +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.pyright] +typeCheckingMode = "strict" +reportPrivateUsage = false +reportUnusedFunction = false +reportUnusedVariable = false +reportUnnecessaryComparison = false +reportUnusedClass = false +enableExperimentalFeatures = true + +[tool.ruff] +target-version = "py312" + +[tool.ruff.lint] +ignore = ["F841"] + +[tool.ruff.format] +skip-magic-trailing-comma = true + +[tool.pytest.ini_options] +python_classes = ["!Test"] +asyncio_mode = "auto" diff --git a/codegen-output/aws-query/src/awsquery/__init__.py b/codegen-output/aws-query/src/awsquery/__init__.py new file mode 100644 index 000000000..30f6d44e9 --- /dev/null +++ b/codegen-output/aws-query/src/awsquery/__init__.py @@ -0,0 +1,3 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +__version__: str = "0.0.1" diff --git a/codegen-output/aws-query/src/awsquery/_private/__init__.py b/codegen-output/aws-query/src/awsquery/_private/__init__.py new file mode 100644 index 000000000..247be3e3d --- /dev/null +++ b/codegen-output/aws-query/src/awsquery/_private/__init__.py @@ -0,0 +1 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. diff --git a/codegen-output/aws-query/src/awsquery/_private/schemas.py b/codegen-output/aws-query/src/awsquery/_private/schemas.py new file mode 100644 index 000000000..316eb5358 --- /dev/null +++ b/codegen-output/aws-query/src/awsquery/_private/schemas.py @@ -0,0 +1,3032 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from types import MappingProxyType + +from smithy_core.prelude import ( + BLOB, + BOOLEAN, + BYTE, + DOUBLE, + FLOAT, + INTEGER, + LONG, + SHORT, + STRING, + TIMESTAMP, + UNIT, +) +from smithy_core.schemas import Schema +from smithy_core.shapes import ShapeID, ShapeType +from smithy_core.traits import Trait + + +DATETIME_OFFSETS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#DatetimeOffsetsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +DATE_TIME = Schema( + id=ShapeID("aws.protocoltests.shared#DateTime"), + shape_type=ShapeType.TIMESTAMP, + traits=[Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time")], +) + +DATETIME_OFFSETS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#DatetimeOffsetsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"datetime": {"target": DATE_TIME}}, +) + +DATETIME_OFFSETS = Schema( + id=ShapeID("aws.protocoltests.query#DatetimeOffsets"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsQueryDateTimeWithNegativeOffset", + "documentation": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n 2019-12-16T22:48:18-01:00\n \n\n', + "params": MappingProxyType({"datetime": 1576540098}), + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "AwsQueryDateTimeWithPositiveOffset", + "documentation": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n 2019-12-17T00:48:18+01:00\n \n\n', + "params": MappingProxyType({"datetime": 1576540098}), + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#EmptyInputAndEmptyOutputInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], +) + +EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#EmptyInputAndEmptyOutputOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], +) + +EMPTY_INPUT_AND_EMPTY_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.query#EmptyInputAndEmptyOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "QueryEmptyInputAndEmptyOutput", + "documentation": "Empty input serializes no extra query params", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=EmptyInputAndEmptyOutput&Version=2020-01-08", + "bodyMediaType": "application/x-www-form-urlencoded", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryEmptyInputAndEmptyOutput", + "documentation": "Empty output", + "protocol": "aws.protocols#awsQuery", + "code": 200, + } + ), + ), + ), + ], +) + +ENDPOINT_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#EndpointOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +ENDPOINT_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#EndpointOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +ENDPOINT_OPERATION = Schema( + id=ShapeID("aws.protocoltests.query#EndpointOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsQueryEndpointTrait", + "documentation": "Operations can prepend to the given host if they define the\nendpoint trait.", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=EndpointOperation&Version=2020-01-08", + "bodyMediaType": "application/x-www-form-urlencoded", + "host": "example.com", + "resolvedHost": "foo.example.com", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#endpoint"), + value=MappingProxyType({"hostPrefix": "foo."}), + ), + ], +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#EndpointWithHostLabelOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.query#HostLabelInput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "label": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#hostLabel")), + Trait.new(id=ShapeID("smithy.api#required")), + ], + } + }, +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#EndpointWithHostLabelOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION = Schema( + id=ShapeID("aws.protocoltests.query#EndpointWithHostLabelOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "AwsQueryEndpointTraitWithHostLabel", + "documentation": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=EndpointWithHostLabelOperation&Version=2020-01-08&label=bar", + "bodyMediaType": "application/x-www-form-urlencoded", + "host": "example.com", + "resolvedHost": "foo.bar.example.com", + "params": MappingProxyType({"label": "bar"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#endpoint"), + value=MappingProxyType({"hostPrefix": "foo.{label}."}), + ), + ], +) + +FLATTENED_XML_MAP_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +FOO_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnum"), + shape_type=ShapeType.ENUM, + members={ + "FOO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Foo")], + }, + "BAZ": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Baz")], + }, + "BAR": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Bar")], + }, + "ONE": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="1")], + }, + "ZERO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="0")], + }, + }, +) + +FOO_ENUM_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnumMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": FOO_ENUM}}, +) + +FLATTENED_XML_MAP_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "myMap": { + "target": FOO_ENUM_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlFlattened"))], + } + }, +) + +FLATTENED_XML_MAP = Schema( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMap"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryQueryFlattenedXmlMap", + "documentation": "Serializes flattened XML maps in responses", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n foo\n Foo\n \n \n baz\n Baz\n \n \n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + {"myMap": MappingProxyType({"foo": "Foo", "baz": "Baz"})} + ), + } + ), + ), + ) + ], +) + +FLATTENED_XML_MAP_WITH_XML_NAME_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapWithXmlNameInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapWithXmlNameOutputMap"), + shape_type=ShapeType.MAP, + members={ + "key": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="K")], + }, + "value": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="V")], + }, + }, +) + +FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapWithXmlNameOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "myMap": { + "target": FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT_MAP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="KVP"), + Trait.new(id=ShapeID("smithy.api#xmlFlattened")), + ], + } + }, +) + +FLATTENED_XML_MAP_WITH_XML_NAME = Schema( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapWithXmlName"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryQueryFlattenedXmlMapWithXmlName", + "documentation": "Serializes flattened XML maps in responses that have xmlName on members", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n a\n A\n \n \n b\n B\n \n \n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + {"myMap": MappingProxyType({"a": "A", "b": "B"})} + ), + } + ), + ), + ) + ], +) + +FLATTENED_XML_MAP_WITH_XML_NAMESPACE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapWithXmlNamespaceInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapWithXmlNamespaceOutputMap"), + shape_type=ShapeType.MAP, + members={ + "key": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="K"), + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "https://the-key.example.com"}), + ), + ], + }, + "value": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="V"), + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "https://the-value.example.com"}), + ), + ], + }, + }, +) + +FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapWithXmlNamespaceOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "myMap": { + "target": FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT_MAP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="KVP"), + Trait.new(id=ShapeID("smithy.api#xmlFlattened")), + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "https://the-member.example.com"}), + ), + ], + } + }, +) + +FLATTENED_XML_MAP_WITH_XML_NAMESPACE = Schema( + id=ShapeID("aws.protocoltests.query#FlattenedXmlMapWithXmlNamespace"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryQueryFlattenedXmlMapWithXmlNamespace", + "documentation": "Serializes flattened XML maps in responses that have xmlNamespace and xmlName on members", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n a\n A\n \n \n b\n B\n \n \n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + {"myMap": MappingProxyType({"a": "A", "b": "B"})} + ), + } + ), + ), + ) + ], +) + +FRACTIONAL_SECONDS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#FractionalSecondsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +FRACTIONAL_SECONDS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#FractionalSecondsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"datetime": {"target": DATE_TIME}}, +) + +FRACTIONAL_SECONDS = Schema( + id=ShapeID("aws.protocoltests.query#FractionalSeconds"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "AwsQueryDateTimeWithFractionalSeconds", + "documentation": "Ensures that clients can correctly parse datetime timestamps with fractional seconds", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n 2000-01-02T20:34:56.123Z\n \n\n', + "params": MappingProxyType({"datetime": 9.46845296123e8}), + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +COMPLEX_NESTED_ERROR_DATA = Schema.collection( + id=ShapeID("aws.protocoltests.query#ComplexNestedErrorData"), + members={"Foo": {"target": STRING}}, +) + +COMPLEX_ERROR = Schema.collection( + id=ShapeID("aws.protocoltests.query#ComplexError"), + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryComplexError", + "protocol": "aws.protocols#awsQuery", + "params": MappingProxyType( + { + "TopLevel": "Top level", + "Nested": MappingProxyType({"Foo": "bar"}), + } + ), + "code": 400, + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "body": "\n \n Sender\n ComplexError\n Top level\n \n bar\n \n \n foo-id\n\n", + "bodyMediaType": "application/xml", + "vendorParamsShape": "aws.protocoltests.config#ErrorCodeParams", + "vendorParams": MappingProxyType( + {"code": "ComplexError", "type": "Sender"} + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="client"), + ], + members={ + "TopLevel": {"target": STRING}, + "Nested": {"target": COMPLEX_NESTED_ERROR_DATA}, + }, +) + +CUSTOM_CODE_ERROR = Schema.collection( + id=ShapeID("aws.protocoltests.query#CustomCodeError"), + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryCustomizedError", + "documentation": "Parses customized XML errors", + "protocol": "aws.protocols#awsQuery", + "params": MappingProxyType({"Message": "Hi"}), + "code": 402, + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "body": "\n \n Sender\n Customized\n Hi\n \n foo-id\n\n", + "bodyMediaType": "application/xml", + "vendorParamsShape": "aws.protocoltests.config#ErrorCodeParams", + "vendorParams": MappingProxyType( + {"code": "Customized", "type": "Sender"} + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="client"), + Trait.new( + id=ShapeID("aws.protocols#awsQueryError"), + value=MappingProxyType({"code": "Customized", "httpResponseCode": 402}), + ), + ], + members={"Message": {"target": STRING}}, +) + +GREETING_WITH_ERRORS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#GreetingWithErrorsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +GREETING_WITH_ERRORS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#GreetingWithErrorsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"greeting": {"target": STRING}}, +) + +INVALID_GREETING = Schema.collection( + id=ShapeID("aws.protocoltests.query#InvalidGreeting"), + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryInvalidGreetingError", + "documentation": "Parses simple XML errors", + "protocol": "aws.protocols#awsQuery", + "params": MappingProxyType({"Message": "Hi"}), + "code": 400, + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "body": "\n \n Sender\n InvalidGreeting\n Hi\n \n foo-id\n\n", + "bodyMediaType": "application/xml", + "vendorParamsShape": "aws.protocoltests.config#ErrorCodeParams", + "vendorParams": MappingProxyType( + {"code": "InvalidGreeting", "type": "Sender"} + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="client"), + ], + members={"Message": {"target": STRING}}, +) + +GREETING_WITH_ERRORS = Schema( + id=ShapeID("aws.protocoltests.query#GreetingWithErrors"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryGreetingWithErrors", + "documentation": "Ensures that operations with errors successfully know how to deserialize the successful response", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "body": '\n \n Hello\n \n\n', + "bodyMediaType": "application/xml", + "params": MappingProxyType({"greeting": "Hello"}), + } + ), + ), + ) + ], +) + +HOST_WITH_PATH_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#HostWithPathOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +HOST_WITH_PATH_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#HostWithPathOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HOST_WITH_PATH_OPERATION = Schema( + id=ShapeID("aws.protocoltests.query#HostWithPathOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "QueryHostWithPath", + "documentation": "Custom endpoints supplied by users can have paths", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/custom/", + "body": "Action=HostWithPathOperation&Version=2020-01-08", + "host": "example.com/custom", + "appliesTo": "client", + } + ), + ), + ) + ], +) + +IGNORES_WRAPPING_XML_NAME_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#IgnoresWrappingXmlNameInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +IGNORES_WRAPPING_XML_NAME_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#IgnoresWrappingXmlNameOutput"), + traits=[ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="IgnoreMe"), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"foo": {"target": STRING}}, +) + +IGNORES_WRAPPING_XML_NAME = Schema( + id=ShapeID("aws.protocoltests.query#IgnoresWrappingXmlName"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryIgnoresWrappingXmlName", + "documentation": "The xmlName trait on the output structure is ignored in AWS Query", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n bar\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"foo": "bar"}), + } + ), + ), + ) + ], +) + +NESTED_STRUCTURES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#NestedStructuresOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +NO_INPUT_AND_NO_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#NoInputAndNoOutputInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +NO_INPUT_AND_NO_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#NoInputAndNoOutputOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +NO_INPUT_AND_NO_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.query#NoInputAndNoOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "QueryNoInputAndNoOutput", + "documentation": "No input serializes no additional query params", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=NoInputAndNoOutput&Version=2020-01-08", + "bodyMediaType": "application/x-www-form-urlencoded", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryNoInputAndNoOutput", + "documentation": "Empty output. Note that no assertion is made on the output body itself.", + "protocol": "aws.protocols#awsQuery", + "code": 200, + } + ), + MappingProxyType( + { + "id": "QueryNoInputAndNoOutputWithResponseMetadata", + "documentation": "Empty output, but the server returns ResponseMetadata.", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": "\n \n abc-123\n \n\n", + } + ), + ), + ), + ], +) + +NO_INPUT_AND_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#NoInputAndOutputInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], +) + +NO_INPUT_AND_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#NoInputAndOutputOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], +) + +NO_INPUT_AND_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.query#NoInputAndOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "QueryNoInputAndOutput", + "documentation": "No input serializes no payload", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=NoInputAndOutput&Version=2020-01-08", + "bodyMediaType": "application/x-www-form-urlencoded", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryNoInputAndOutput", + "documentation": "Empty output", + "protocol": "aws.protocols#awsQuery", + "code": 200, + } + ), + ), + ), + ], +) + +PUT_WITH_CONTENT_ENCODING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#PutWithContentEncodingInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "encoding": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="Content-Encoding") + ], + }, + "data": {"target": STRING}, + }, +) + +PUT_WITH_CONTENT_ENCODING_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#PutWithContentEncodingOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +PUT_WITH_CONTENT_ENCODING = Schema( + id=ShapeID("aws.protocoltests.query#PutWithContentEncoding"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "SDKAppliedContentEncoding_awsQuery", + "documentation": "Compression algorithm encoding is appended to the Content-Encoding header.", + "protocol": "aws.protocols#awsQuery", + "params": MappingProxyType( + { + "data": "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\n" + } + ), + "method": "POST", + "uri": "/", + "headers": MappingProxyType({"Content-Encoding": "gzip"}), + } + ), + MappingProxyType( + { + "id": "SDKAppendsGzipAndIgnoresHttpProvidedEncoding_awsQuery", + "documentation": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is NOT in the Content-Encoding header since HTTP binding\ntraits are ignored in the awsQuery protocol.\n", + "protocol": "aws.protocols#awsQuery", + "params": MappingProxyType( + { + "encoding": "custom", + "data": "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\n", + } + ), + "method": "POST", + "uri": "/", + "headers": MappingProxyType({"Content-Encoding": "gzip"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#requestCompression"), + value=MappingProxyType({"encodings": ("gzip",)}), + ), + ], +) + +QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#QueryIdempotencyTokenAutoFillInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "token": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#idempotencyToken"))], + } + }, +) + +QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#QueryIdempotencyTokenAutoFillOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL = Schema( + id=ShapeID("aws.protocoltests.query#QueryIdempotencyTokenAutoFill"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "QueryProtocolIdempotencyTokenAutoFill", + "documentation": "Automatically adds idempotency token when not set", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=QueryIdempotencyTokenAutoFill&Version=2020-01-08&token=00000000-0000-4000-8000-000000000000", + "bodyMediaType": "application/x-www-form-urlencoded", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "QueryProtocolIdempotencyTokenAutoFillIsSet", + "documentation": "Uses the given idempotency token as-is", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=QueryIdempotencyTokenAutoFill&Version=2020-01-08&token=00000000-0000-4000-8000-000000000123", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + {"token": "00000000-0000-4000-8000-000000000123"} + ), + "appliesTo": "client", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + ], +) + +GREETING_STRUCT = Schema.collection( + id=ShapeID("aws.protocoltests.shared#GreetingStruct"), + members={"hi": {"target": STRING}}, +) + +GREETING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#GreetingList"), + shape_type=ShapeType.LIST, + members={"member": {"target": GREETING_STRUCT}}, +) + +STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING}}, +) + +LIST_WITH_XML_NAME = Schema.collection( + id=ShapeID("aws.protocoltests.query#ListWithXmlName"), + shape_type=ShapeType.LIST, + members={ + "member": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="item")], + } + }, +) + +NESTED_STRUCT_WITH_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.query#NestedStructWithList"), + members={"ListArg": {"target": STRING_LIST}}, +) + +QUERY_LISTS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#QueryListsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "ListArg": {"target": STRING_LIST}, + "ComplexListArg": {"target": GREETING_LIST}, + "FlattenedListArg": { + "target": STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlFlattened"))], + }, + "ListArgWithXmlNameMember": {"target": LIST_WITH_XML_NAME}, + "FlattenedListArgWithXmlName": { + "target": LIST_WITH_XML_NAME, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="Hi"), + Trait.new(id=ShapeID("smithy.api#xmlFlattened")), + ], + }, + "NestedWithList": {"target": NESTED_STRUCT_WITH_LIST}, + }, +) + +QUERY_LISTS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#QueryListsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +QUERY_LISTS = Schema( + id=ShapeID("aws.protocoltests.query#QueryLists"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "QueryLists", + "documentation": "Serializes query lists", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryLists&Version=2020-01-08&ListArg.member.1=foo&ListArg.member.2=bar&ListArg.member.3=baz&ComplexListArg.member.1.hi=hello&ComplexListArg.member.2.hi=hola", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "ListArg": ("foo", "bar", "baz"), + "ComplexListArg": ( + MappingProxyType({"hi": "hello"}), + MappingProxyType({"hi": "hola"}), + ), + } + ), + } + ), + MappingProxyType( + { + "id": "EmptyQueryLists", + "documentation": "Serializes empty query lists", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryLists&Version=2020-01-08&ListArg=", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"ListArg": ()}), + } + ), + MappingProxyType( + { + "id": "FlattenedQueryLists", + "documentation": "Flattens query lists by repeating the member name and removing the member element", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryLists&Version=2020-01-08&FlattenedListArg.1=A&FlattenedListArg.2=B", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"FlattenedListArg": ("A", "B")}), + } + ), + MappingProxyType( + { + "id": "QueryListArgWithXmlNameMember", + "documentation": "Changes the member of lists using xmlName trait", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryLists&Version=2020-01-08&ListArgWithXmlNameMember.item.1=A&ListArgWithXmlNameMember.item.2=B", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + {"ListArgWithXmlNameMember": ("A", "B")} + ), + } + ), + MappingProxyType( + { + "id": "QueryFlattenedListArgWithXmlName", + "documentation": "Changes the name of flattened lists using xmlName trait on the structure member", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryLists&Version=2020-01-08&Hi.1=A&Hi.2=B", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + {"FlattenedListArgWithXmlName": ("A", "B")} + ), + } + ), + MappingProxyType( + { + "id": "QueryNestedStructWithList", + "documentation": "Nested structure with a list member", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryLists&Version=2020-01-08&NestedWithList.ListArg.member.1=A&NestedWithList.ListArg.member.2=B", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "NestedWithList": MappingProxyType( + {"ListArg": ("A", "B")} + ) + } + ), + } + ), + ), + ) + ], +) + +COMPLEX_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.query#ComplexMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": GREETING_STRUCT}}, +) + +STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +MAP_WITH_XML_NAME = Schema.collection( + id=ShapeID("aws.protocoltests.query#MapWithXmlName"), + shape_type=ShapeType.MAP, + members={ + "key": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="K")], + }, + "value": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="V")], + }, + }, +) + +MAP_OF_LISTS = Schema.collection( + id=ShapeID("aws.protocoltests.query#MapOfLists"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING_LIST}}, +) + +NESTED_STRUCT_WITH_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.query#NestedStructWithMap"), + members={"MapArg": {"target": STRING_MAP}}, +) + +QUERY_MAPS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#QueryMapsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "MapArg": {"target": STRING_MAP}, + "RenamedMapArg": { + "target": STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="Foo")], + }, + "ComplexMapArg": {"target": COMPLEX_MAP}, + "MapWithXmlMemberName": {"target": MAP_WITH_XML_NAME}, + "FlattenedMap": { + "target": STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlFlattened"))], + }, + "FlattenedMapWithXmlName": { + "target": MAP_WITH_XML_NAME, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="Hi"), + Trait.new(id=ShapeID("smithy.api#xmlFlattened")), + ], + }, + "MapOfLists": {"target": MAP_OF_LISTS}, + "NestedStructWithMap": {"target": NESTED_STRUCT_WITH_MAP}, + }, +) + +QUERY_MAPS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#QueryMapsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +QUERY_MAPS = Schema( + id=ShapeID("aws.protocoltests.query#QueryMaps"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "QuerySimpleQueryMaps", + "documentation": "Serializes query maps", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryMaps&Version=2020-01-08&MapArg.entry.1.key=bar&MapArg.entry.1.value=Bar&MapArg.entry.2.key=foo&MapArg.entry.2.value=Foo", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + {"MapArg": MappingProxyType({"bar": "Bar", "foo": "Foo"})} + ), + } + ), + MappingProxyType( + { + "id": "QuerySimpleQueryMapsWithXmlName", + "documentation": "Serializes query maps and uses xmlName", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryMaps&Version=2020-01-08&Foo.entry.1.key=foo&Foo.entry.1.value=Foo", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + {"RenamedMapArg": MappingProxyType({"foo": "Foo"})} + ), + } + ), + MappingProxyType( + { + "id": "QueryComplexQueryMaps", + "documentation": "Serializes complex query maps", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryMaps&Version=2020-01-08&ComplexMapArg.entry.1.key=bar&ComplexMapArg.entry.1.value.hi=Bar&ComplexMapArg.entry.2.key=foo&ComplexMapArg.entry.2.value.hi=Foo", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "ComplexMapArg": MappingProxyType( + { + "bar": MappingProxyType({"hi": "Bar"}), + "foo": MappingProxyType({"hi": "Foo"}), + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "QueryEmptyQueryMaps", + "documentation": "Does not serialize empty query maps", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryMaps&Version=2020-01-08", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"MapArg": MappingProxyType({})}), + } + ), + MappingProxyType( + { + "id": "QueryQueryMapWithMemberXmlName", + "documentation": "Serializes query maps where the member has an xmlName trait", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryMaps&Version=2020-01-08&MapWithXmlMemberName.entry.1.K=bar&MapWithXmlMemberName.entry.1.V=Bar&MapWithXmlMemberName.entry.2.K=foo&MapWithXmlMemberName.entry.2.V=Foo", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "MapWithXmlMemberName": MappingProxyType( + {"bar": "Bar", "foo": "Foo"} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "QueryFlattenedQueryMaps", + "documentation": "Serializes flattened query maps", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryMaps&Version=2020-01-08&FlattenedMap.1.key=bar&FlattenedMap.1.value=Bar&FlattenedMap.2.key=foo&FlattenedMap.2.value=Foo", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "FlattenedMap": MappingProxyType( + {"bar": "Bar", "foo": "Foo"} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "QueryFlattenedQueryMapsWithXmlName", + "documentation": "Serializes flattened query maps that use an xmlName", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryMaps&Version=2020-01-08&Hi.1.K=bar&Hi.1.V=Bar&Hi.2.K=foo&Hi.2.V=Foo", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "FlattenedMapWithXmlName": MappingProxyType( + {"bar": "Bar", "foo": "Foo"} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "QueryQueryMapOfLists", + "documentation": "Serializes query map of lists", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryMaps&Version=2020-01-08&MapOfLists.entry.1.key=bar&MapOfLists.entry.1.value.member.1=C&MapOfLists.entry.1.value.member.2=D&MapOfLists.entry.2.key=foo&MapOfLists.entry.2.value.member.1=A&MapOfLists.entry.2.value.member.2=B", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "MapOfLists": MappingProxyType( + {"bar": ("C", "D"), "foo": ("A", "B")} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "QueryNestedStructWithMap", + "documentation": "Serializes nested struct with map member", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "body": "Action=QueryMaps&Version=2020-01-08&NestedStructWithMap.MapArg.entry.1.key=bar&NestedStructWithMap.MapArg.entry.1.value=Bar&NestedStructWithMap.MapArg.entry.2.key=foo&NestedStructWithMap.MapArg.entry.2.value=Foo", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "NestedStructWithMap": MappingProxyType( + { + "MapArg": MappingProxyType( + {"bar": "Bar", "foo": "Foo"} + ) + } + ) + } + ), + } + ), + ), + ) + ], +) + +EPOCH_SECONDS = Schema( + id=ShapeID("aws.protocoltests.shared#EpochSeconds"), + shape_type=ShapeType.TIMESTAMP, + traits=[Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds")], +) + +QUERY_TIMESTAMPS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#QueryTimestampsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "normalFormat": {"target": TIMESTAMP}, + "epochMember": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ) + ], + }, + "epochTarget": {"target": EPOCH_SECONDS}, + }, +) + +QUERY_TIMESTAMPS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#QueryTimestampsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +QUERY_TIMESTAMPS = Schema( + id=ShapeID("aws.protocoltests.query#QueryTimestamps"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "QueryTimestampsInput", + "documentation": "Serializes timestamps", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=QueryTimestamps&Version=2020-01-08&normalFormat=2015-01-25T08%3A00%3A00Z&epochMember=1422172800&epochTarget=1422172800", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "normalFormat": 1422172800, + "epochMember": 1422172800, + "epochTarget": 1422172800, + } + ), + } + ), + ), + ) + ], +) + +RECURSIVE_XML_SHAPES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#RecursiveXmlShapesInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +INTEGER_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnum"), + shape_type=ShapeType.INT_ENUM, + traits=[Trait.new(id=ShapeID("smithy.api#box"))], + members={ + "A": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=1)], + }, + "B": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=2)], + }, + "C": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=3)], + }, + }, +) + +SIMPLE_INPUT_PARAMS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#SimpleInputParamsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "Foo": {"target": STRING}, + "Bar": {"target": STRING}, + "Baz": {"target": BOOLEAN}, + "Bam": {"target": INTEGER}, + "FloatValue": {"target": FLOAT}, + "Boo": {"target": DOUBLE}, + "Qux": {"target": BLOB}, + "FooEnum": {"target": FOO_ENUM}, + "IntegerEnum": {"target": INTEGER_ENUM}, + }, +) + +SIMPLE_INPUT_PARAMS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#SimpleInputParamsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +SIMPLE_INPUT_PARAMS = Schema( + id=ShapeID("aws.protocoltests.query#SimpleInputParams"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "QuerySimpleInputParamsStrings", + "documentation": "Serializes strings", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=SimpleInputParams&Version=2020-01-08&Foo=val1&Bar=val2", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"Foo": "val1", "Bar": "val2"}), + } + ), + MappingProxyType( + { + "id": "QuerySimpleInputParamsStringAndBooleanTrue", + "documentation": "Serializes booleans that are true", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=SimpleInputParams&Version=2020-01-08&Foo=val1&Baz=true", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"Foo": "val1", "Baz": True}), + } + ), + MappingProxyType( + { + "id": "QuerySimpleInputParamsStringsAndBooleanFalse", + "documentation": "Serializes booleans that are false", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=SimpleInputParams&Version=2020-01-08&Baz=false", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"Baz": False}), + } + ), + MappingProxyType( + { + "id": "QuerySimpleInputParamsInteger", + "documentation": "Serializes integers", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=SimpleInputParams&Version=2020-01-08&Bam=10", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"Bam": 10}), + } + ), + MappingProxyType( + { + "id": "QuerySimpleInputParamsFloat", + "documentation": "Serializes floats", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=SimpleInputParams&Version=2020-01-08&Boo=10.8", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"Boo": 10.8}), + } + ), + MappingProxyType( + { + "id": "QuerySimpleInputParamsBlob", + "documentation": "Blobs are base64 encoded in the query string", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=SimpleInputParams&Version=2020-01-08&Qux=dmFsdWU%3D", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"Qux": "value"}), + } + ), + MappingProxyType( + { + "id": "QueryEnums", + "documentation": "Serializes enums in the query string", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=SimpleInputParams&Version=2020-01-08&FooEnum=Foo", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"FooEnum": "Foo"}), + } + ), + MappingProxyType( + { + "id": "QueryIntEnums", + "documentation": "Serializes intEnums in the query string", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=SimpleInputParams&Version=2020-01-08&IntegerEnum=1", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType({"IntegerEnum": 1}), + } + ), + MappingProxyType( + { + "id": "AwsQuerySupportsNaNFloatInputs", + "documentation": "Supports handling NaN float values.", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FloatValue=NaN&Boo=NaN", + "bodyMediaType": "application/x-www-form-urlencoded", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"FloatValue": "NaN", "Boo": "NaN"}), + } + ), + MappingProxyType( + { + "id": "AwsQuerySupportsInfinityFloatInputs", + "documentation": "Supports handling Infinity float values.", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FloatValue=Infinity&Boo=Infinity", + "bodyMediaType": "application/x-www-form-urlencoded", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"FloatValue": "Infinity", "Boo": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "AwsQuerySupportsNegativeInfinityFloatInputs", + "documentation": "Supports handling -Infinity float values.", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "body": "Action=SimpleInputParams&Version=2020-01-08&FloatValue=-Infinity&Boo=-Infinity", + "bodyMediaType": "application/x-www-form-urlencoded", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"FloatValue": "-Infinity", "Boo": "-Infinity"} + ), + } + ), + ), + ) + ], +) + +SIMPLE_SCALAR_XML_PROPERTIES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#SimpleScalarXmlPropertiesInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#SimpleScalarXmlPropertiesOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "stringValue": {"target": STRING}, + "emptyStringValue": {"target": STRING}, + "trueBooleanValue": {"target": BOOLEAN}, + "falseBooleanValue": {"target": BOOLEAN}, + "byteValue": {"target": BYTE}, + "shortValue": {"target": SHORT}, + "integerValue": {"target": INTEGER}, + "longValue": {"target": LONG}, + "floatValue": {"target": FLOAT}, + "doubleValue": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="DoubleDribble") + ], + }, + }, +) + +SIMPLE_SCALAR_XML_PROPERTIES = Schema( + id=ShapeID("aws.protocoltests.query#SimpleScalarXmlProperties"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QuerySimpleScalarProperties", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n string\n \n true\n false\n 1\n 2\n 3\n 4\n 5.5\n 6.5\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + { + "stringValue": "string", + "emptyStringValue": "", + "trueBooleanValue": True, + "falseBooleanValue": False, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5, + } + ), + } + ), + MappingProxyType( + { + "id": "AwsQuerySupportsNaNFloatOutputs", + "documentation": "Supports handling NaN float values.", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n NaN\n NaN\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + {"floatValue": "NaN", "doubleValue": "NaN"} + ), + } + ), + MappingProxyType( + { + "id": "AwsQuerySupportsInfinityFloatOutputs", + "documentation": "Supports handling Infinity float values.", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n Infinity\n Infinity\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + {"floatValue": "Infinity", "doubleValue": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "AwsQuerySupportsNegativeInfinityFloatOutputs", + "documentation": "Supports handling -Infinity float values.", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n -Infinity\n -Infinity\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + {"floatValue": "-Infinity", "doubleValue": "-Infinity"} + ), + } + ), + ), + ) + ], +) + +XML_BLOBS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlBlobsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +XML_BLOBS_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlBlobsOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.query#XmlBlobsOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"data": {"target": BLOB}}, +) + +XML_BLOBS = Schema( + id=ShapeID("aws.protocoltests.query#XmlBlobs"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlBlobs", + "documentation": "Blobs are base64 encoded", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n dmFsdWU=\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"data": "value"}), + } + ), + ), + ) + ], +) + +XML_EMPTY_BLOBS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlEmptyBlobsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +XML_EMPTY_BLOBS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlEmptyBlobsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.query#XmlBlobsOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"data": {"target": BLOB}}, +) + +XML_EMPTY_BLOBS = Schema( + id=ShapeID("aws.protocoltests.query#XmlEmptyBlobs"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlEmptyBlobs", + "documentation": "Empty blobs are deserialized as empty string", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"data": ""}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "QueryXmlEmptySelfClosedBlobs", + "documentation": "Empty self closed blobs are deserialized as empty string", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"data": ""}), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +XML_EMPTY_LISTS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlEmptyListsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +BOOLEAN_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#BooleanList"), + shape_type=ShapeType.LIST, + members={"member": {"target": BOOLEAN}}, +) + +FOO_ENUM_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnumList"), + shape_type=ShapeType.LIST, + members={"member": {"target": FOO_ENUM}}, +) + +RENAMED_LIST_MEMBERS = Schema.collection( + id=ShapeID("aws.protocoltests.query#RenamedListMembers"), + shape_type=ShapeType.LIST, + members={ + "member": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="item")], + } + }, +) + +LIST_WITH_MEMBER_NAMESPACE = Schema.collection( + id=ShapeID("aws.protocoltests.query#ListWithMemberNamespace"), + shape_type=ShapeType.LIST, + traits=[ + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "https://xml-list.example.com"}), + ) + ], + members={ + "member": { + "target": STRING, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "https://xml-member.example.com"}), + ) + ], + } + }, +) + +LIST_WITH_NAMESPACE = Schema.collection( + id=ShapeID("aws.protocoltests.query#ListWithNamespace"), + shape_type=ShapeType.LIST, + traits=[ + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "https://xml-list.example.com"}), + ) + ], + members={"member": {"target": STRING}}, +) + +INTEGER_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerList"), + shape_type=ShapeType.LIST, + members={"member": {"target": INTEGER}}, +) + +INTEGER_ENUM_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnumList"), + shape_type=ShapeType.LIST, + members={"member": {"target": INTEGER_ENUM}}, +) + +NESTED_STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#NestedStringList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING_LIST}}, +) + +STRING_SET = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringSet"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#uniqueItems"))], + members={"member": {"target": STRING}}, +) + +STRUCTURE_LIST_MEMBER = Schema.collection( + id=ShapeID("aws.protocoltests.query#StructureListMember"), + members={ + "a": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="value")], + }, + "b": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="other")], + }, + }, +) + +STRUCTURE_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.query#StructureList"), + shape_type=ShapeType.LIST, + members={ + "member": { + "target": STRUCTURE_LIST_MEMBER, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="item")], + } + }, +) + +TIMESTAMP_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#TimestampList"), + shape_type=ShapeType.LIST, + members={"member": {"target": TIMESTAMP}}, +) + +XML_EMPTY_LISTS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlEmptyListsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.query#XmlListsOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "stringList": {"target": STRING_LIST}, + "stringSet": {"target": STRING_SET}, + "integerList": {"target": INTEGER_LIST}, + "booleanList": {"target": BOOLEAN_LIST}, + "timestampList": {"target": TIMESTAMP_LIST}, + "enumList": {"target": FOO_ENUM_LIST}, + "intEnumList": {"target": INTEGER_ENUM_LIST}, + "nestedStringList": {"target": NESTED_STRING_LIST}, + "renamedListMembers": { + "target": RENAMED_LIST_MEMBERS, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="renamed")], + }, + "flattenedList": { + "target": RENAMED_LIST_MEMBERS, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#suppress"), value=("XmlFlattenedTrait",) + ), + Trait.new(id=ShapeID("smithy.api#xmlFlattened")), + ], + }, + "flattenedList2": { + "target": RENAMED_LIST_MEMBERS, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="customName"), + Trait.new(id=ShapeID("smithy.api#xmlFlattened")), + ], + }, + "flattenedListWithMemberNamespace": { + "target": LIST_WITH_MEMBER_NAMESPACE, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlFlattened"))], + }, + "flattenedListWithNamespace": { + "target": LIST_WITH_NAMESPACE, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlFlattened"))], + }, + "structureList": { + "target": STRUCTURE_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="myStructureList") + ], + }, + }, +) + +XML_EMPTY_LISTS = Schema( + id=ShapeID("aws.protocoltests.query#XmlEmptyLists"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlEmptyLists", + "documentation": "Deserializes empty XML lists", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"stringList": (), "stringSet": ()}), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +XML_EMPTY_MAPS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlEmptyMapsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +XML_MAPS_OUTPUT_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlMapsOutputMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": GREETING_STRUCT}}, +) + +XML_EMPTY_MAPS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlEmptyMapsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.query#XmlMapsOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"myMap": {"target": XML_MAPS_OUTPUT_MAP}}, +) + +XML_EMPTY_MAPS = Schema( + id=ShapeID("aws.protocoltests.query#XmlEmptyMaps"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlEmptyMaps", + "documentation": "Deserializes Empty XML maps", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"myMap": MappingProxyType({})}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "QueryXmlEmptySelfClosedMaps", + "documentation": "Deserializes Self-Closed XML maps", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"myMap": MappingProxyType({})}), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +XML_ENUMS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlEnumsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +FOO_ENUM_SET = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnumSet"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#uniqueItems"))], + members={"member": {"target": FOO_ENUM}}, +) + +XML_ENUMS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlEnumsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "fooEnum1": {"target": FOO_ENUM}, + "fooEnum2": {"target": FOO_ENUM}, + "fooEnum3": {"target": FOO_ENUM}, + "fooEnumList": {"target": FOO_ENUM_LIST}, + "fooEnumSet": {"target": FOO_ENUM_SET}, + "fooEnumMap": {"target": FOO_ENUM_MAP}, + }, +) + +XML_ENUMS = Schema( + id=ShapeID("aws.protocoltests.query#XmlEnums"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlEnums", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n Foo\n 0\n 1\n \n Foo\n 0\n \n \n Foo\n 0\n \n \n \n hi\n Foo\n \n \n zero\n 0\n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": ("Foo", "0"), + "fooEnumSet": ("Foo", "0"), + "fooEnumMap": MappingProxyType( + {"hi": "Foo", "zero": "0"} + ), + } + ), + } + ), + ), + ) + ], +) + +XML_INT_ENUMS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlIntEnumsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +INTEGER_ENUM_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnumMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": INTEGER_ENUM}}, +) + +INTEGER_ENUM_SET = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnumSet"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#uniqueItems"))], + members={"member": {"target": INTEGER_ENUM}}, +) + +XML_INT_ENUMS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlIntEnumsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "intEnum1": {"target": INTEGER_ENUM}, + "intEnum2": {"target": INTEGER_ENUM}, + "intEnum3": {"target": INTEGER_ENUM}, + "intEnumList": {"target": INTEGER_ENUM_LIST}, + "intEnumSet": {"target": INTEGER_ENUM_SET}, + "intEnumMap": {"target": INTEGER_ENUM_MAP}, + }, +) + +XML_INT_ENUMS = Schema( + id=ShapeID("aws.protocoltests.query#XmlIntEnums"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlIntEnums", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n 1\n 2\n 3\n \n 1\n 2\n \n \n 1\n 2\n \n \n \n a\n 1\n \n \n b\n 2\n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + { + "intEnum1": 1, + "intEnum2": 2, + "intEnum3": 3, + "intEnumList": (1, 2), + "intEnumSet": (1, 2), + "intEnumMap": MappingProxyType({"a": 1, "b": 2}), + } + ), + } + ), + ), + ) + ], +) + +XML_LISTS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlListsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +XML_LISTS_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlListsOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.query#XmlListsOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "stringList": {"target": STRING_LIST}, + "stringSet": {"target": STRING_SET}, + "integerList": {"target": INTEGER_LIST}, + "booleanList": {"target": BOOLEAN_LIST}, + "timestampList": {"target": TIMESTAMP_LIST}, + "enumList": {"target": FOO_ENUM_LIST}, + "intEnumList": {"target": INTEGER_ENUM_LIST}, + "nestedStringList": {"target": NESTED_STRING_LIST}, + "renamedListMembers": { + "target": RENAMED_LIST_MEMBERS, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="renamed")], + }, + "flattenedList": { + "target": RENAMED_LIST_MEMBERS, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#suppress"), value=("XmlFlattenedTrait",) + ), + Trait.new(id=ShapeID("smithy.api#xmlFlattened")), + ], + }, + "flattenedList2": { + "target": RENAMED_LIST_MEMBERS, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="customName"), + Trait.new(id=ShapeID("smithy.api#xmlFlattened")), + ], + }, + "flattenedListWithMemberNamespace": { + "target": LIST_WITH_MEMBER_NAMESPACE, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlFlattened"))], + }, + "flattenedListWithNamespace": { + "target": LIST_WITH_NAMESPACE, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlFlattened"))], + }, + "structureList": { + "target": STRUCTURE_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#xmlName"), value="myStructureList") + ], + }, + }, +) + +XML_LISTS = Schema( + id=ShapeID("aws.protocoltests.query#XmlLists"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlLists", + "documentation": "Tests for XML list serialization", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n foo\n bar\n \n \n foo\n bar\n \n \n 1\n 2\n \n \n true\n false\n \n \n 2014-04-29T18:30:38Z\n 2014-04-29T18:30:38Z\n \n \n Foo\n 0\n \n \n 1\n 2\n \n \n \n foo\n bar\n \n \n baz\n qux\n \n \n \n foo\n bar\n \n hi\n bye\n yep\n nope\n a\n b\n a\n b\n \n \n 1\n 2\n \n \n 3\n 4\n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + { + "stringList": ("foo", "bar"), + "stringSet": ("foo", "bar"), + "integerList": (1, 2), + "booleanList": (True, False), + "timestampList": (1398796238, 1398796238), + "enumList": ("Foo", "0"), + "intEnumList": (1, 2), + "nestedStringList": (("foo", "bar"), ("baz", "qux")), + "renamedListMembers": ("foo", "bar"), + "flattenedList": ("hi", "bye"), + "flattenedList2": ("yep", "nope"), + "flattenedListWithMemberNamespace": ("a", "b"), + "flattenedListWithNamespace": ("a", "b"), + "structureList": ( + MappingProxyType({"a": "1", "b": "2"}), + MappingProxyType({"a": "3", "b": "4"}), + ), + } + ), + } + ), + ), + ) + ], +) + +XML_MAPS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlMapsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +XML_MAPS_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlMapsOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.query#XmlMapsOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"myMap": {"target": XML_MAPS_OUTPUT_MAP}}, +) + +XML_MAPS = Schema( + id=ShapeID("aws.protocoltests.query#XmlMaps"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlMaps", + "documentation": "Tests for XML map serialization", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + { + "myMap": MappingProxyType( + { + "foo": MappingProxyType({"hi": "there"}), + "baz": MappingProxyType({"hi": "bye"}), + } + ) + } + ), + } + ), + ), + ) + ], +) + +XML_MAPS_XML_NAME_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlMapsXmlNameInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +XML_MAPS_XML_NAME_OUTPUT_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlMapsXmlNameOutputMap"), + shape_type=ShapeType.MAP, + members={ + "key": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="Attribute")], + }, + "value": { + "target": GREETING_STRUCT, + "traits": [Trait.new(id=ShapeID("smithy.api#xmlName"), value="Setting")], + }, + }, +) + +XML_MAPS_XML_NAME_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlMapsXmlNameOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"myMap": {"target": XML_MAPS_XML_NAME_OUTPUT_MAP}}, +) + +XML_MAPS_XML_NAME = Schema( + id=ShapeID("aws.protocoltests.query#XmlMapsXmlName"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryQueryXmlMapsXmlName", + "documentation": "Serializes XML lists", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + { + "myMap": MappingProxyType( + { + "foo": MappingProxyType({"hi": "there"}), + "baz": MappingProxyType({"hi": "bye"}), + } + ) + } + ), + } + ), + ), + ) + ], +) + +XML_NAMESPACES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlNamespacesInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +XML_NAMESPACED_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlNamespacedList"), + shape_type=ShapeType.LIST, + members={ + "member": { + "target": STRING, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "http://bux.com"}), + ) + ], + } + }, +) + +XML_NAMESPACE_NESTED = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlNamespaceNested"), + traits=[ + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "http://boo.com"}), + ) + ], + members={ + "foo": { + "target": STRING, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "http://baz.com", "prefix": "baz"}), + ) + ], + }, + "values": { + "target": XML_NAMESPACED_LIST, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "http://qux.com"}), + ) + ], + }, + }, +) + +XML_NAMESPACES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlNamespacesOutput"), + traits=[ + Trait.new(id=ShapeID("smithy.api#output")), + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "http://foo.com"}), + ), + ], + members={"nested": {"target": XML_NAMESPACE_NESTED}}, +) + +XML_NAMESPACES = Schema( + id=ShapeID("aws.protocoltests.query#XmlNamespaces"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlNamespaces", + "documentation": "Serializes XML namespaces", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n Foo\n \n Bar\n Baz\n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + { + "nested": MappingProxyType( + {"foo": "Foo", "values": ("Bar", "Baz")} + ) + } + ), + } + ), + ), + ) + ], +) + +XML_TIMESTAMPS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlTimestampsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +HTTP_DATE = Schema( + id=ShapeID("aws.protocoltests.shared#HttpDate"), + shape_type=ShapeType.TIMESTAMP, + traits=[Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date")], +) + +XML_TIMESTAMPS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#XmlTimestampsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "normal": {"target": TIMESTAMP}, + "dateTime": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time") + ], + }, + "dateTimeOnTarget": {"target": DATE_TIME}, + "epochSeconds": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ) + ], + }, + "epochSecondsOnTarget": {"target": EPOCH_SECONDS}, + "httpDate": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date") + ], + }, + "httpDateOnTarget": {"target": HTTP_DATE}, + }, +) + +XML_TIMESTAMPS = Schema( + id=ShapeID("aws.protocoltests.query#XmlTimestamps"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryXmlTimestamps", + "documentation": "Tests how normal timestamps are serialized", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n 2014-04-29T18:30:38Z\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"normal": 1398796238}), + } + ), + MappingProxyType( + { + "id": "QueryXmlTimestampsWithDateTimeFormat", + "documentation": "Ensures that the timestampFormat of date-time works like normal timestamps", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n 2014-04-29T18:30:38Z\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"dateTime": 1398796238}), + } + ), + MappingProxyType( + { + "id": "QueryXmlTimestampsWithDateTimeOnTargetFormat", + "documentation": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n 2014-04-29T18:30:38Z\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"dateTimeOnTarget": 1398796238}), + } + ), + MappingProxyType( + { + "id": "QueryXmlTimestampsWithEpochSecondsFormat", + "documentation": "Ensures that the timestampFormat of epoch-seconds works", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n 1398796238\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"epochSeconds": 1398796238}), + } + ), + MappingProxyType( + { + "id": "QueryXmlTimestampsWithEpochSecondsOnTargetFormat", + "documentation": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n 1398796238\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + {"epochSecondsOnTarget": 1398796238} + ), + } + ), + MappingProxyType( + { + "id": "QueryXmlTimestampsWithHttpDateFormat", + "documentation": "Ensures that the timestampFormat of http-date works", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n Tue, 29 Apr 2014 18:30:38 GMT\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"httpDate": 1398796238}), + } + ), + MappingProxyType( + { + "id": "QueryXmlTimestampsWithHttpDateOnTargetFormat", + "documentation": "Ensures that the timestampFormat of http-date on the target shape works", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n Tue, 29 Apr 2014 18:30:38 GMT\n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType({"httpDateOnTarget": 1398796238}), + } + ), + ), + ) + ], +) + +STRUCT_ARG = Schema.collection( + id=ShapeID("aws.protocoltests.query#StructArg"), + members={ + "StringArg": {"target": STRING}, + "OtherArg": {"target": BOOLEAN}, + # This needs to reference a schema that isn't defined yet. + # It will be populated with a non-null value at the end of the file. + "RecursiveArg": None, + }, +) + +NESTED_STRUCTURES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#NestedStructuresInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"Nested": {"target": STRUCT_ARG}}, +) + +RECURSIVE_XML_SHAPES_OUTPUT_NESTED1 = Schema.collection( + id=ShapeID("aws.protocoltests.query#RecursiveXmlShapesOutputNested1"), + members={ + "foo": {"target": STRING}, + # This needs to reference a schema that isn't defined yet. + # It will be populated with a non-null value at the end of the file. + "nested": None, + }, +) + +RECURSIVE_XML_SHAPES_OUTPUT_NESTED2 = Schema.collection( + id=ShapeID("aws.protocoltests.query#RecursiveXmlShapesOutputNested2"), + members={ + "bar": {"target": STRING}, + "recursiveMember": {"target": RECURSIVE_XML_SHAPES_OUTPUT_NESTED1}, + }, +) + +NESTED_STRUCTURES = Schema( + id=ShapeID("aws.protocoltests.query#NestedStructures"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "NestedStructures", + "documentation": "Serializes nested structures using dots", + "protocol": "aws.protocols#awsQuery", + "method": "POST", + "uri": "/", + "headers": MappingProxyType( + {"Content-Type": "application/x-www-form-urlencoded"} + ), + "requireHeaders": ("Content-Length",), + "body": "Action=NestedStructures&Version=2020-01-08&Nested.StringArg=foo&Nested.OtherArg=true&Nested.RecursiveArg.StringArg=baz", + "bodyMediaType": "application/x-www-form-urlencoded", + "params": MappingProxyType( + { + "Nested": MappingProxyType( + { + "StringArg": "foo", + "OtherArg": True, + "RecursiveArg": MappingProxyType( + {"StringArg": "baz"} + ), + } + ) + } + ), + } + ), + ), + ) + ], +) + +RECURSIVE_XML_SHAPES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.query#RecursiveXmlShapesOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"nested": {"target": RECURSIVE_XML_SHAPES_OUTPUT_NESTED1}}, +) + +RECURSIVE_XML_SHAPES = Schema( + id=ShapeID("aws.protocoltests.query#RecursiveXmlShapes"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "QueryRecursiveShapes", + "documentation": "Serializes recursive structures", + "protocol": "aws.protocols#awsQuery", + "code": 200, + "body": '\n \n \n Foo1\n \n Bar1\n \n Foo2\n \n Bar2\n \n \n \n \n \n\n', + "bodyMediaType": "application/xml", + "headers": MappingProxyType({"Content-Type": "text/xml"}), + "params": MappingProxyType( + { + "nested": MappingProxyType( + { + "foo": "Foo1", + "nested": MappingProxyType( + { + "bar": "Bar1", + "recursiveMember": MappingProxyType( + { + "foo": "Foo2", + "nested": MappingProxyType( + {"bar": "Bar2"} + ), + } + ), + } + ), + } + ) + } + ), + } + ), + ), + ) + ], +) + +AWS_QUERY = Schema( + id=ShapeID("aws.protocoltests.query#AwsQuery"), + shape_type=ShapeType.SERVICE, + traits=[ + Trait.new( + id=ShapeID("aws.auth#sigv4"), value=MappingProxyType({"name": "awsquery"}) + ), + Trait.new( + id=ShapeID("smithy.api#title"), value="Sample Query Protocol Service" + ), + Trait.new(id=ShapeID("aws.protocols#awsQuery")), + Trait.new( + id=ShapeID("aws.api#service"), + value=MappingProxyType({"sdkId": "Query Protocol"}), + ), + Trait.new( + id=ShapeID("smithy.api#xmlNamespace"), + value=MappingProxyType({"uri": "https://example.com/"}), + ), + ], +) + +RECURSIVE_XML_SHAPES_OUTPUT_NESTED1.members["nested"] = Schema.member( + id=RECURSIVE_XML_SHAPES_OUTPUT_NESTED1.id.with_member("nested"), + target=RECURSIVE_XML_SHAPES_OUTPUT_NESTED2, + index=1, +) + +STRUCT_ARG.members["RecursiveArg"] = Schema.member( + id=STRUCT_ARG.id.with_member("RecursiveArg"), target=STRUCT_ARG, index=2 +) diff --git a/codegen-output/aws-query/src/awsquery/auth.py b/codegen-output/aws-query/src/awsquery/auth.py new file mode 100644 index 000000000..24ca90fec --- /dev/null +++ b/codegen-output/aws-query/src/awsquery/auth.py @@ -0,0 +1,31 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from typing import Any + +from smithy_core.auth import AuthOption as _smithy_core_auth_AuthOption, AuthParams +from smithy_core.interfaces.auth import ( + AuthOption as _smithy_core_interfaces_auth_AuthOption, +) +from smithy_core.shapes import ShapeID + + +class HTTPAuthSchemeResolver: + def resolve_auth_scheme( + self, auth_parameters: AuthParams[Any, Any] + ) -> list[_smithy_core_interfaces_auth_AuthOption]: + auth_options: list[_smithy_core_interfaces_auth_AuthOption] = [] + + if (option := _generate_sigv4_option(auth_parameters)) is not None: + auth_options.append(option) + + return auth_options + + +def _generate_sigv4_option( + auth_params: AuthParams[Any, Any], +) -> _smithy_core_interfaces_auth_AuthOption | None: + return _smithy_core_auth_AuthOption( + scheme_id=ShapeID("aws.auth#sigv4"), + identity_properties={}, # type: ignore + signer_properties={}, # type: ignore + ) diff --git a/codegen-output/aws-query/src/awsquery/client.py b/codegen-output/aws-query/src/awsquery/client.py new file mode 100644 index 000000000..a1a43e228 --- /dev/null +++ b/codegen-output/aws-query/src/awsquery/client.py @@ -0,0 +1,2448 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +import asyncio +from copy import deepcopy +import logging +from typing import Any, Self, cast + +from smithy_aws_core.config import ConfigSource +from smithy_aws_core.identity import AWSCredentialsIdentity +from smithy_aws_core.identity.chain import IdentityChain +from smithy_core.aio.client import ClientCall, RequestPipeline +from smithy_core.aio.retries import RetryStrategyResolver +from smithy_core.aio.utils import close +from smithy_core.exceptions import ExpectationNotMetError +from smithy_core.interceptors import InterceptorChain +from smithy_core.types import TypedProperties +from smithy_http.aio.interfaces import HTTPClient +from smithy_http.plugins import user_agent_plugin + +from .config import AsyncQueryProtocolConfig, Plugin +from .models import ( + DATETIME_OFFSETS, + DatetimeOffsetsInput, + DatetimeOffsetsOutput, + EMPTY_INPUT_AND_EMPTY_OUTPUT, + ENDPOINT_OPERATION, + ENDPOINT_WITH_HOST_LABEL_OPERATION, + EmptyInputAndEmptyOutputInput, + EmptyInputAndEmptyOutputOutput, + EndpointOperationInput, + EndpointOperationOutput, + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + FLATTENED_XML_MAP, + FLATTENED_XML_MAP_WITH_XML_NAME, + FLATTENED_XML_MAP_WITH_XML_NAMESPACE, + FRACTIONAL_SECONDS, + FlattenedXmlMapInput, + FlattenedXmlMapOutput, + FlattenedXmlMapWithXmlNameInput, + FlattenedXmlMapWithXmlNameOutput, + FlattenedXmlMapWithXmlNamespaceInput, + FlattenedXmlMapWithXmlNamespaceOutput, + FractionalSecondsInput, + FractionalSecondsOutput, + GREETING_WITH_ERRORS, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HOST_WITH_PATH_OPERATION, + HostWithPathOperationInput, + HostWithPathOperationOutput, + IGNORES_WRAPPING_XML_NAME, + IgnoresWrappingXmlNameInput, + IgnoresWrappingXmlNameOutput, + NESTED_STRUCTURES, + NO_INPUT_AND_NO_OUTPUT, + NO_INPUT_AND_OUTPUT, + NestedStructuresInput, + NestedStructuresOutput, + NoInputAndNoOutputInput, + NoInputAndNoOutputOutput, + NoInputAndOutputInput, + NoInputAndOutputOutput, + PUT_WITH_CONTENT_ENCODING, + PutWithContentEncodingInput, + PutWithContentEncodingOutput, + QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL, + QUERY_LISTS, + QUERY_MAPS, + QUERY_TIMESTAMPS, + QueryIdempotencyTokenAutoFillInput, + QueryIdempotencyTokenAutoFillOutput, + QueryListsInput, + QueryListsOutput, + QueryMapsInput, + QueryMapsOutput, + QueryTimestampsInput, + QueryTimestampsOutput, + RECURSIVE_XML_SHAPES, + RecursiveXmlShapesInput, + RecursiveXmlShapesOutput, + SIMPLE_INPUT_PARAMS, + SIMPLE_SCALAR_XML_PROPERTIES, + SimpleInputParamsInput, + SimpleInputParamsOutput, + SimpleScalarXmlPropertiesInput, + SimpleScalarXmlPropertiesOutput, + XML_BLOBS, + XML_EMPTY_BLOBS, + XML_EMPTY_LISTS, + XML_EMPTY_MAPS, + XML_ENUMS, + XML_INT_ENUMS, + XML_LISTS, + XML_MAPS, + XML_MAPS_XML_NAME, + XML_NAMESPACES, + XML_TIMESTAMPS, + XmlBlobsInput, + XmlBlobsOperationOutput, + XmlEmptyBlobsInput, + XmlEmptyBlobsOutput, + XmlEmptyListsInput, + XmlEmptyListsOutput, + XmlEmptyMapsInput, + XmlEmptyMapsOutput, + XmlEnumsInput, + XmlEnumsOutput, + XmlIntEnumsInput, + XmlIntEnumsOutput, + XmlListsInput, + XmlListsOperationOutput, + XmlMapsInput, + XmlMapsOperationOutput, + XmlMapsXmlNameInput, + XmlMapsXmlNameOutput, + XmlNamespacesInput, + XmlNamespacesOutput, + XmlTimestampsInput, + XmlTimestampsOutput, +) +from .user_agent import aws_user_agent_plugin + + +logger = logging.getLogger(__name__) + + +class AsyncQueryProtocolClient: + """A query service that sends query requests and XML responses.""" + + def __init__( + self, + config: AsyncQueryProtocolConfig | None = None, + plugins: list[Plugin] | None = None, + ): + """ + Constructor for `AsyncQueryProtocolClient`. + + Args: + config: + Optional configuration for the client. Here you can set things like + the endpoint for HTTP services or auth credentials. + plugins: + A list of callables applied once to the client's base configuration. + Their changes are inherited by every operation invocation. + """ + self._config = config + self._plugins = plugins + self._derive_lock = asyncio.Lock() + self._setup_done = False + self._closed = False + self._retry_strategy_resolver = RetryStrategyResolver() + self._client_plugins: list[Plugin] = [aws_user_agent_plugin, user_agent_plugin] + + async def _ensure_setup(self) -> None: + if not self._setup_done: + async with self._derive_lock: + if not self._setup_done: + if self._config is None: + config = await AsyncQueryProtocolConfig.resolve() + else: + # Copy so plugins don't mutate the caller's config. + config = deepcopy(self._config) + for plugin in self._client_plugins: + plugin(config) + if self._plugins: + for plugin in self._plugins: + plugin(config) + self._config = config + + if self._config.aws_credentials_identity_resolver is None: + config_context = self._config.resolution_context() + config_file = None + profile_name = None + if config_context is not None: + config_file = await config_context.parsed_profiles() + if config_context.profile_source is ConfigSource.OVERRIDE: + profile_name = config_context.profile_name + self._config.aws_credentials_identity_resolver = ( + await IdentityChain.create( + AWSCredentialsIdentity, + config_file=config_file, + profile_name=profile_name, + region_override=self._config.region, + http_client=cast( + HTTPClient | None, self._config.transport + ), + ) + ) + self._setup_done = True + + async def close(self) -> None: + """Close this client and any resources held by its transport.""" + if self._closed: + return + async with self._derive_lock: + if self._closed: + return + self._closed = True + if self._setup_done and self._config is not None: + await close(self._config.transport) + + async def __aenter__(self) -> Self: + if self._closed: + raise RuntimeError("Cannot enter a client that has been closed.") + return self + + async def __aexit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: + await self.close() + + async def datetime_offsets( + self, input: DatetimeOffsetsInput, plugins: list[Plugin] | None = None + ) -> DatetimeOffsetsOutput: + """ + Invokes the DatetimeOffsets operation. + + Args: + input: + An instance of `DatetimeOffsetsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `DatetimeOffsetsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=DATETIME_OFFSETS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def empty_input_and_empty_output( + self, input: EmptyInputAndEmptyOutputInput, plugins: list[Plugin] | None = None + ) -> EmptyInputAndEmptyOutputOutput: + """ + The example tests how requests and responses are serialized when + there's no request or response members. While this should be rare, code + generators must support this. + + Args: + input: + An instance of `EmptyInputAndEmptyOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EmptyInputAndEmptyOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=EMPTY_INPUT_AND_EMPTY_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def endpoint_operation( + self, input: EndpointOperationInput, plugins: list[Plugin] | None = None + ) -> EndpointOperationOutput: + """ + Invokes the EndpointOperation operation. + + Args: + input: + An instance of `EndpointOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EndpointOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=ENDPOINT_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def endpoint_with_host_label_operation( + self, + input: EndpointWithHostLabelOperationInput, + plugins: list[Plugin] | None = None, + ) -> EndpointWithHostLabelOperationOutput: + """ + Invokes the EndpointWithHostLabelOperation operation. + + Args: + input: + An instance of `EndpointWithHostLabelOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EndpointWithHostLabelOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=ENDPOINT_WITH_HOST_LABEL_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def flattened_xml_map( + self, input: FlattenedXmlMapInput, plugins: list[Plugin] | None = None + ) -> FlattenedXmlMapOutput: + """ + Flattened maps + + Args: + input: + An instance of `FlattenedXmlMapInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `FlattenedXmlMapOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=FLATTENED_XML_MAP, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def flattened_xml_map_with_xml_name( + self, + input: FlattenedXmlMapWithXmlNameInput, + plugins: list[Plugin] | None = None, + ) -> FlattenedXmlMapWithXmlNameOutput: + """ + Flattened maps with @xmlName + + Args: + input: + An instance of `FlattenedXmlMapWithXmlNameInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `FlattenedXmlMapWithXmlNameOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=FLATTENED_XML_MAP_WITH_XML_NAME, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def flattened_xml_map_with_xml_namespace( + self, + input: FlattenedXmlMapWithXmlNamespaceInput, + plugins: list[Plugin] | None = None, + ) -> FlattenedXmlMapWithXmlNamespaceOutput: + """ + Flattened maps with @xmlNamespace and @xmlName + + Args: + input: + An instance of `FlattenedXmlMapWithXmlNamespaceInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `FlattenedXmlMapWithXmlNamespaceOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=FLATTENED_XML_MAP_WITH_XML_NAMESPACE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def fractional_seconds( + self, input: FractionalSecondsInput, plugins: list[Plugin] | None = None + ) -> FractionalSecondsOutput: + """ + Invokes the FractionalSeconds operation. + + Args: + input: + An instance of `FractionalSecondsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `FractionalSecondsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=FRACTIONAL_SECONDS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def greeting_with_errors( + self, input: GreetingWithErrorsInput, plugins: list[Plugin] | None = None + ) -> GreetingWithErrorsOutput: + """ + This operation has three possible return values: 1. A successful + response in the form of GreetingWithErrorsOutput 2. An InvalidGreeting + error. 3. A BadRequest error. + + Args: + input: + An instance of `GreetingWithErrorsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `GreetingWithErrorsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=GREETING_WITH_ERRORS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def host_with_path_operation( + self, input: HostWithPathOperationInput, plugins: list[Plugin] | None = None + ) -> HostWithPathOperationOutput: + """ + Invokes the HostWithPathOperation operation. + + Args: + input: + An instance of `HostWithPathOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HostWithPathOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HOST_WITH_PATH_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def ignores_wrapping_xml_name( + self, input: IgnoresWrappingXmlNameInput, plugins: list[Plugin] | None = None + ) -> IgnoresWrappingXmlNameOutput: + """ + The xmlName trait on the output structure is ignored in AWS Query. The + wrapping element is always operation name + \"Response\", and inside of + that wrapper is another wrapper named operation name + \"Result\". + + Args: + input: + An instance of `IgnoresWrappingXmlNameInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `IgnoresWrappingXmlNameOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=IGNORES_WRAPPING_XML_NAME, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def nested_structures( + self, input: NestedStructuresInput, plugins: list[Plugin] | None = None + ) -> NestedStructuresOutput: + """ + This test serializes nested and recursive structure members. + + Args: + input: + An instance of `NestedStructuresInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NestedStructuresOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NESTED_STRUCTURES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def no_input_and_no_output( + self, input: NoInputAndNoOutputInput, plugins: list[Plugin] | None = None + ) -> NoInputAndNoOutputOutput: + """ + The example tests how requests and responses are serialized when + there's no request or response payload because the operation has no + input or output. While this should be rare, code generators must support + this. + + Args: + input: + An instance of `NoInputAndNoOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NoInputAndNoOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NO_INPUT_AND_NO_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def no_input_and_output( + self, input: NoInputAndOutputInput, plugins: list[Plugin] | None = None + ) -> NoInputAndOutputOutput: + """ + The example tests how requests and responses are serialized when + there's no request payload or response members. While this should be + rare, code generators must support this. + + Args: + input: + An instance of `NoInputAndOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NoInputAndOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NO_INPUT_AND_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def put_with_content_encoding( + self, input: PutWithContentEncodingInput, plugins: list[Plugin] | None = None + ) -> PutWithContentEncodingOutput: + """ + Invokes the PutWithContentEncoding operation. + + Args: + input: + An instance of `PutWithContentEncodingInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `PutWithContentEncodingOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=PUT_WITH_CONTENT_ENCODING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def query_idempotency_token_auto_fill( + self, + input: QueryIdempotencyTokenAutoFillInput, + plugins: list[Plugin] | None = None, + ) -> QueryIdempotencyTokenAutoFillOutput: + """ + Automatically adds idempotency tokens. + + Args: + input: + An instance of `QueryIdempotencyTokenAutoFillInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `QueryIdempotencyTokenAutoFillOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def query_lists( + self, input: QueryListsInput, plugins: list[Plugin] | None = None + ) -> QueryListsOutput: + """ + This test serializes simple and complex lists. + + Args: + input: + An instance of `QueryListsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `QueryListsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=QUERY_LISTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def query_maps( + self, input: QueryMapsInput, plugins: list[Plugin] | None = None + ) -> QueryMapsOutput: + """ + This test serializes simple and complex maps. + + Args: + input: + An instance of `QueryMapsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `QueryMapsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=QUERY_MAPS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def query_timestamps( + self, input: QueryTimestampsInput, plugins: list[Plugin] | None = None + ) -> QueryTimestampsOutput: + """ + This test serializes timestamps. 1. Timestamps are serialized as RFC + 3339 date-time values by default. 2. A timestampFormat trait on a member + changes the format. 3. A timestampFormat trait on the shape targeted by + the member changes the format. + + Args: + input: + An instance of `QueryTimestampsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `QueryTimestampsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=QUERY_TIMESTAMPS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def recursive_xml_shapes( + self, input: RecursiveXmlShapesInput, plugins: list[Plugin] | None = None + ) -> RecursiveXmlShapesOutput: + """ + Recursive shapes + + Args: + input: + An instance of `RecursiveXmlShapesInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `RecursiveXmlShapesOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=RECURSIVE_XML_SHAPES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def simple_input_params( + self, input: SimpleInputParamsInput, plugins: list[Plugin] | None = None + ) -> SimpleInputParamsOutput: + """ + This test serializes strings, numbers, and boolean values. + + Args: + input: + An instance of `SimpleInputParamsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `SimpleInputParamsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=SIMPLE_INPUT_PARAMS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def simple_scalar_xml_properties( + self, input: SimpleScalarXmlPropertiesInput, plugins: list[Plugin] | None = None + ) -> SimpleScalarXmlPropertiesOutput: + """ + Invokes the SimpleScalarXmlProperties operation. + + Args: + input: + An instance of `SimpleScalarXmlPropertiesInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `SimpleScalarXmlPropertiesOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=SIMPLE_SCALAR_XML_PROPERTIES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_blobs( + self, input: XmlBlobsInput, plugins: list[Plugin] | None = None + ) -> XmlBlobsOperationOutput: + """ + Blobs are base64 encoded + + Args: + input: + An instance of `XmlBlobsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlBlobsOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_BLOBS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_empty_blobs( + self, input: XmlEmptyBlobsInput, plugins: list[Plugin] | None = None + ) -> XmlEmptyBlobsOutput: + """ + Invokes the XmlEmptyBlobs operation. + + Args: + input: + An instance of `XmlEmptyBlobsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlEmptyBlobsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_EMPTY_BLOBS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_empty_lists( + self, input: XmlEmptyListsInput, plugins: list[Plugin] | None = None + ) -> XmlEmptyListsOutput: + """ + Invokes the XmlEmptyLists operation. + + Args: + input: + An instance of `XmlEmptyListsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlEmptyListsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_EMPTY_LISTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_empty_maps( + self, input: XmlEmptyMapsInput, plugins: list[Plugin] | None = None + ) -> XmlEmptyMapsOutput: + """ + Invokes the XmlEmptyMaps operation. + + Args: + input: + An instance of `XmlEmptyMapsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlEmptyMapsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_EMPTY_MAPS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_enums( + self, input: XmlEnumsInput, plugins: list[Plugin] | None = None + ) -> XmlEnumsOutput: + """ + This example serializes enums as top level properties, in lists, sets, + and maps. + + Args: + input: + An instance of `XmlEnumsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlEnumsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_ENUMS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_int_enums( + self, input: XmlIntEnumsInput, plugins: list[Plugin] | None = None + ) -> XmlIntEnumsOutput: + """ + This example serializes enums as top level properties, in lists, sets, + and maps. + + Args: + input: + An instance of `XmlIntEnumsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlIntEnumsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_INT_ENUMS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_lists( + self, input: XmlListsInput, plugins: list[Plugin] | None = None + ) -> XmlListsOperationOutput: + """ + This test case serializes XML lists for the following cases for both + input and output: 1. Normal XML lists. 2. Normal XML sets. 3. XML lists + of lists. 4. XML lists with @xmlName on its members 5. Flattened XML + lists. 6. Flattened XML lists with @xmlName. 7. Lists of structures. + + Args: + input: + An instance of `XmlListsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlListsOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_LISTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_maps( + self, input: XmlMapsInput, plugins: list[Plugin] | None = None + ) -> XmlMapsOperationOutput: + """ + The example tests basic map serialization. + + Args: + input: + An instance of `XmlMapsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlMapsOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_MAPS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_maps_xml_name( + self, input: XmlMapsXmlNameInput, plugins: list[Plugin] | None = None + ) -> XmlMapsXmlNameOutput: + """ + Invokes the XmlMapsXmlName operation. + + Args: + input: + An instance of `XmlMapsXmlNameInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlMapsXmlNameOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_MAPS_XML_NAME, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_namespaces( + self, input: XmlNamespacesInput, plugins: list[Plugin] | None = None + ) -> XmlNamespacesOutput: + """ + Invokes the XmlNamespaces operation. + + Args: + input: + An instance of `XmlNamespacesInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlNamespacesOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_NAMESPACES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def xml_timestamps( + self, input: XmlTimestampsInput, plugins: list[Plugin] | None = None + ) -> XmlTimestampsOutput: + """ + This tests how timestamps are serialized, including using the default + format of date-time and various @timestampFormat trait values. + + Args: + input: + An instance of `XmlTimestampsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `XmlTimestampsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=XML_TIMESTAMPS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) diff --git a/codegen-output/aws-query/src/awsquery/config.py b/codegen-output/aws-query/src/awsquery/config.py new file mode 100644 index 000000000..2bdc192e7 --- /dev/null +++ b/codegen-output/aws-query/src/awsquery/config.py @@ -0,0 +1,285 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from dataclasses import dataclass, field +from typing import Any, Callable, ClassVar, Self, TypeAlias, Union, Unpack + +from smithy_aws_core.aio.protocols import AwsQueryClientProtocol +from smithy_aws_core.auth import SigV4AuthScheme +from smithy_aws_core.config import AwsConfigOverrides, FileSystem +from smithy_aws_core.config.aws_config import AsyncAwsConfig +from smithy_aws_core.config.resolvers import EndpointUriResolver +from smithy_aws_core.config.types import FieldSpec +from smithy_aws_core.endpoints.standard_regional import ( + StandardRegionalEndpointsResolver, +) +from smithy_aws_core.identity import AWSCredentialsIdentity, AWSIdentityProperties +from smithy_core.aio.interfaces import ClientProtocol, EndpointResolver +from smithy_core.aio.interfaces.auth import AuthScheme +from smithy_core.aio.interfaces.identity import IdentityResolver +from smithy_core.interceptors import Interceptor +from smithy_core.shapes import ShapeID +from smithy_http.aio.aiohttp import AIOHTTPClient + +from ._private.schemas import AWS_QUERY as _SCHEMA_AWS_QUERY +from .auth import HTTPAuthSchemeResolver +from .models import ( + DatetimeOffsetsInput, + DatetimeOffsetsOutput, + EmptyInputAndEmptyOutputInput, + EmptyInputAndEmptyOutputOutput, + EndpointOperationInput, + EndpointOperationOutput, + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + FlattenedXmlMapInput, + FlattenedXmlMapOutput, + FlattenedXmlMapWithXmlNameInput, + FlattenedXmlMapWithXmlNameOutput, + FlattenedXmlMapWithXmlNamespaceInput, + FlattenedXmlMapWithXmlNamespaceOutput, + FractionalSecondsInput, + FractionalSecondsOutput, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HostWithPathOperationInput, + HostWithPathOperationOutput, + IgnoresWrappingXmlNameInput, + IgnoresWrappingXmlNameOutput, + NestedStructuresInput, + NestedStructuresOutput, + NoInputAndNoOutputInput, + NoInputAndNoOutputOutput, + NoInputAndOutputInput, + NoInputAndOutputOutput, + PutWithContentEncodingInput, + PutWithContentEncodingOutput, + QueryIdempotencyTokenAutoFillInput, + QueryIdempotencyTokenAutoFillOutput, + QueryListsInput, + QueryListsOutput, + QueryMapsInput, + QueryMapsOutput, + QueryTimestampsInput, + QueryTimestampsOutput, + RecursiveXmlShapesInput, + RecursiveXmlShapesOutput, + SimpleInputParamsInput, + SimpleInputParamsOutput, + SimpleScalarXmlPropertiesInput, + SimpleScalarXmlPropertiesOutput, + XmlBlobsInput, + XmlBlobsOperationOutput, + XmlEmptyBlobsInput, + XmlEmptyBlobsOutput, + XmlEmptyListsInput, + XmlEmptyListsOutput, + XmlEmptyMapsInput, + XmlEmptyMapsOutput, + XmlEnumsInput, + XmlEnumsOutput, + XmlIntEnumsInput, + XmlIntEnumsOutput, + XmlListsInput, + XmlListsOperationOutput, + XmlMapsInput, + XmlMapsOperationOutput, + XmlMapsXmlNameInput, + XmlMapsXmlNameOutput, + XmlNamespacesInput, + XmlNamespacesOutput, + XmlTimestampsInput, + XmlTimestampsOutput, +) + + +_ServiceInterceptor = Union[ + Interceptor[DatetimeOffsetsInput, DatetimeOffsetsOutput, Any, Any], + Interceptor[ + EmptyInputAndEmptyOutputInput, EmptyInputAndEmptyOutputOutput, Any, Any + ], + Interceptor[EndpointOperationInput, EndpointOperationOutput, Any, Any], + Interceptor[ + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + Any, + Any, + ], + Interceptor[FlattenedXmlMapInput, FlattenedXmlMapOutput, Any, Any], + Interceptor[ + FlattenedXmlMapWithXmlNameInput, FlattenedXmlMapWithXmlNameOutput, Any, Any + ], + Interceptor[ + FlattenedXmlMapWithXmlNamespaceInput, + FlattenedXmlMapWithXmlNamespaceOutput, + Any, + Any, + ], + Interceptor[FractionalSecondsInput, FractionalSecondsOutput, Any, Any], + Interceptor[GreetingWithErrorsInput, GreetingWithErrorsOutput, Any, Any], + Interceptor[HostWithPathOperationInput, HostWithPathOperationOutput, Any, Any], + Interceptor[IgnoresWrappingXmlNameInput, IgnoresWrappingXmlNameOutput, Any, Any], + Interceptor[NestedStructuresInput, NestedStructuresOutput, Any, Any], + Interceptor[NoInputAndNoOutputInput, NoInputAndNoOutputOutput, Any, Any], + Interceptor[NoInputAndOutputInput, NoInputAndOutputOutput, Any, Any], + Interceptor[PutWithContentEncodingInput, PutWithContentEncodingOutput, Any, Any], + Interceptor[ + QueryIdempotencyTokenAutoFillInput, + QueryIdempotencyTokenAutoFillOutput, + Any, + Any, + ], + Interceptor[QueryListsInput, QueryListsOutput, Any, Any], + Interceptor[QueryMapsInput, QueryMapsOutput, Any, Any], + Interceptor[QueryTimestampsInput, QueryTimestampsOutput, Any, Any], + Interceptor[RecursiveXmlShapesInput, RecursiveXmlShapesOutput, Any, Any], + Interceptor[SimpleInputParamsInput, SimpleInputParamsOutput, Any, Any], + Interceptor[ + SimpleScalarXmlPropertiesInput, SimpleScalarXmlPropertiesOutput, Any, Any + ], + Interceptor[XmlBlobsInput, XmlBlobsOperationOutput, Any, Any], + Interceptor[XmlEmptyBlobsInput, XmlEmptyBlobsOutput, Any, Any], + Interceptor[XmlEmptyListsInput, XmlEmptyListsOutput, Any, Any], + Interceptor[XmlEmptyMapsInput, XmlEmptyMapsOutput, Any, Any], + Interceptor[XmlEnumsInput, XmlEnumsOutput, Any, Any], + Interceptor[XmlIntEnumsInput, XmlIntEnumsOutput, Any, Any], + Interceptor[XmlListsInput, XmlListsOperationOutput, Any, Any], + Interceptor[XmlMapsInput, XmlMapsOperationOutput, Any, Any], + Interceptor[XmlMapsXmlNameInput, XmlMapsXmlNameOutput, Any, Any], + Interceptor[XmlNamespacesInput, XmlNamespacesOutput, Any, Any], + Interceptor[XmlTimestampsInput, XmlTimestampsOutput, Any, Any], +] + + +class _AsyncQueryProtocolConfigOverrides(AwsConfigOverrides, total=False): + endpoint_resolver: EndpointResolver | None + protocol: ClientProtocol[Any, Any] | None + auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None + auth_scheme_resolver: HTTPAuthSchemeResolver | None + + +@dataclass(kw_only=True, repr=False, init=False) +class AsyncQueryProtocolConfig(AsyncAwsConfig): + """Query Protocol configuration (async-resolved).""" + + endpoint_resolver: EndpointResolver | None = None + """ + The endpoint resolver used to resolve the final endpoint per-operation + based on the configuration. + """ + + protocol: ClientProtocol[Any, Any] | None = None + """The protocol to serialize and deserialize requests with.""" + + interceptors: list[_ServiceInterceptor] = field(default_factory=lambda: []) + """ + The list of interceptors, which are hooks that are called during the + execution of a request. + """ + + auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None = None + """A map of auth scheme ids to auth schemes.""" + + auth_scheme_resolver: HTTPAuthSchemeResolver | None = None + """ + An auth scheme resolver that determines the auth scheme for each + operation. + """ + + aws_credentials_identity_resolver: ( + IdentityResolver[AWSCredentialsIdentity, AWSIdentityProperties] | None + ) = None + """Resolves AWS Credentials. Required for operations that use Sigv4 Auth.""" + + region: str | None = None + """ + The AWS region to connect to. The configured region is used to determine + the service endpoint. + """ + + aws_access_key_id: str | None = None + """The identifier for a secret access key.""" + + aws_secret_access_key: str | None = None + """A secret access key that can be used to sign requests.""" + + aws_session_token: str | None = None + """The session token used with temporary AWS credentials.""" + + user_agent_extra: str | None = None + """Additional suffix to be added to the User-Agent header.""" + + sdk_ua_app_id: str | None = None + """ + A unique and opaque application ID that is appended to the User-Agent + header. + """ + + _FIELDS: ClassVar[dict[str, FieldSpec]] = { + "aws_credentials_identity_resolver": FieldSpec(default=None), + "region": FieldSpec(default=None), + "aws_access_key_id": FieldSpec(default=None), + "aws_secret_access_key": FieldSpec(default=None), + "aws_session_token": FieldSpec(default=None), + "user_agent_extra": FieldSpec(default=None), + "sdk_ua_app_id": FieldSpec(default=None), + **AsyncAwsConfig._FIELDS, + "endpoint_uri": FieldSpec( + default=None, resolver=EndpointUriResolver("query_protocol") + ), + "endpoint_resolver": FieldSpec( + default_factory=lambda: StandardRegionalEndpointsResolver( + endpoint_prefix="awsquery" + ) + ), + "protocol": FieldSpec( + default_factory=lambda: AwsQueryClientProtocol( + _SCHEMA_AWS_QUERY, "2020-01-08" + ) + ), + "auth_schemes": FieldSpec( + default_factory=lambda: { + ShapeID("aws.auth#sigv4"): SigV4AuthScheme(service="awsquery") + } + ), + "auth_scheme_resolver": FieldSpec(default_factory=HTTPAuthSchemeResolver), + "transport": FieldSpec(default_factory=lambda: AIOHTTPClient()), + } + + def set_auth_scheme(self, scheme: AuthScheme[Any, Any, Any, Any]) -> None: + """ + Set an auth scheme implementation using its scheme ID. :param scheme: + The auth scheme to add or replace. + """ + auth_schemes = dict(self.auth_schemes or {}) + auth_schemes[scheme.scheme_id] = scheme + self.auth_schemes = auth_schemes + + @classmethod + async def resolve( # pyright: ignore[reportIncompatibleMethodOverride] + cls, + *, + profile: str | None = None, + fs: FileSystem | None = None, + config_file_path: str | None = None, + credentials_file_path: str | None = None, + **overrides: Unpack[_AsyncQueryProtocolConfigOverrides], + ) -> Self: + """ + Resolve config from environment, config files, defaults, and explicit + overrides. + """ + return await cls._resolve( + profile=profile, + fs=fs, + config_file_path=config_file_path, + credentials_file_path=credentials_file_path, + overrides=overrides, + ) + + +Plugin: TypeAlias = Callable[[AsyncQueryProtocolConfig], None] +""" +A callable that customizes a client configuration. Service-level plugins +are applied once to the base configuration inherited by every operation. +Operation-level plugins apply only to a single operation invocation. +""" diff --git a/codegen-output/aws-query/src/awsquery/models.py b/codegen-output/aws-query/src/awsquery/models.py new file mode 100644 index 000000000..be31c9db4 --- /dev/null +++ b/codegen-output/aws-query/src/awsquery/models.py @@ -0,0 +1,4982 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from dataclasses import dataclass +from datetime import datetime +from enum import IntEnum, StrEnum +import logging +from typing import Any, Literal, Self + +from smithy_core.deserializers import ShapeDeserializer +from smithy_core.documents import TypeRegistry +from smithy_core.exceptions import ModeledError +from smithy_core.schemas import APIOperation, Schema +from smithy_core.serializers import ShapeSerializer +from smithy_core.shapes import ShapeID +from smithy_core.types import UnknownEnumMixin + +from ._private.schemas import ( + COMPLEX_ERROR as _SCHEMA_COMPLEX_ERROR, + COMPLEX_NESTED_ERROR_DATA as _SCHEMA_COMPLEX_NESTED_ERROR_DATA, + CUSTOM_CODE_ERROR as _SCHEMA_CUSTOM_CODE_ERROR, + DATETIME_OFFSETS as _SCHEMA_DATETIME_OFFSETS, + DATETIME_OFFSETS_INPUT as _SCHEMA_DATETIME_OFFSETS_INPUT, + DATETIME_OFFSETS_OUTPUT as _SCHEMA_DATETIME_OFFSETS_OUTPUT, + EMPTY_INPUT_AND_EMPTY_OUTPUT as _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT, + EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT as _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, + EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT as _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, + ENDPOINT_OPERATION as _SCHEMA_ENDPOINT_OPERATION, + ENDPOINT_OPERATION_INPUT as _SCHEMA_ENDPOINT_OPERATION_INPUT, + ENDPOINT_OPERATION_OUTPUT as _SCHEMA_ENDPOINT_OPERATION_OUTPUT, + ENDPOINT_WITH_HOST_LABEL_OPERATION as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION, + ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, + ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, + FLATTENED_XML_MAP as _SCHEMA_FLATTENED_XML_MAP, + FLATTENED_XML_MAP_INPUT as _SCHEMA_FLATTENED_XML_MAP_INPUT, + FLATTENED_XML_MAP_OUTPUT as _SCHEMA_FLATTENED_XML_MAP_OUTPUT, + FLATTENED_XML_MAP_WITH_XML_NAME as _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME, + FLATTENED_XML_MAP_WITH_XML_NAMESPACE as _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE, + FLATTENED_XML_MAP_WITH_XML_NAMESPACE_INPUT as _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_INPUT, + FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT as _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT, + FLATTENED_XML_MAP_WITH_XML_NAME_INPUT as _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_INPUT, + FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT as _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT, + FRACTIONAL_SECONDS as _SCHEMA_FRACTIONAL_SECONDS, + FRACTIONAL_SECONDS_INPUT as _SCHEMA_FRACTIONAL_SECONDS_INPUT, + FRACTIONAL_SECONDS_OUTPUT as _SCHEMA_FRACTIONAL_SECONDS_OUTPUT, + GREETING_STRUCT as _SCHEMA_GREETING_STRUCT, + GREETING_WITH_ERRORS as _SCHEMA_GREETING_WITH_ERRORS, + GREETING_WITH_ERRORS_INPUT as _SCHEMA_GREETING_WITH_ERRORS_INPUT, + GREETING_WITH_ERRORS_OUTPUT as _SCHEMA_GREETING_WITH_ERRORS_OUTPUT, + HOST_WITH_PATH_OPERATION as _SCHEMA_HOST_WITH_PATH_OPERATION, + HOST_WITH_PATH_OPERATION_INPUT as _SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, + HOST_WITH_PATH_OPERATION_OUTPUT as _SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, + IGNORES_WRAPPING_XML_NAME as _SCHEMA_IGNORES_WRAPPING_XML_NAME, + IGNORES_WRAPPING_XML_NAME_INPUT as _SCHEMA_IGNORES_WRAPPING_XML_NAME_INPUT, + IGNORES_WRAPPING_XML_NAME_OUTPUT as _SCHEMA_IGNORES_WRAPPING_XML_NAME_OUTPUT, + INVALID_GREETING as _SCHEMA_INVALID_GREETING, + NESTED_STRUCTURES as _SCHEMA_NESTED_STRUCTURES, + NESTED_STRUCTURES_INPUT as _SCHEMA_NESTED_STRUCTURES_INPUT, + NESTED_STRUCTURES_OUTPUT as _SCHEMA_NESTED_STRUCTURES_OUTPUT, + NESTED_STRUCT_WITH_LIST as _SCHEMA_NESTED_STRUCT_WITH_LIST, + NESTED_STRUCT_WITH_MAP as _SCHEMA_NESTED_STRUCT_WITH_MAP, + NO_INPUT_AND_NO_OUTPUT as _SCHEMA_NO_INPUT_AND_NO_OUTPUT, + NO_INPUT_AND_NO_OUTPUT_INPUT as _SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, + NO_INPUT_AND_NO_OUTPUT_OUTPUT as _SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, + NO_INPUT_AND_OUTPUT as _SCHEMA_NO_INPUT_AND_OUTPUT, + NO_INPUT_AND_OUTPUT_INPUT as _SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, + NO_INPUT_AND_OUTPUT_OUTPUT as _SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, + PUT_WITH_CONTENT_ENCODING as _SCHEMA_PUT_WITH_CONTENT_ENCODING, + PUT_WITH_CONTENT_ENCODING_INPUT as _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, + PUT_WITH_CONTENT_ENCODING_OUTPUT as _SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, + QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL as _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL, + QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT as _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT, + QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT as _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT, + QUERY_LISTS as _SCHEMA_QUERY_LISTS, + QUERY_LISTS_INPUT as _SCHEMA_QUERY_LISTS_INPUT, + QUERY_LISTS_OUTPUT as _SCHEMA_QUERY_LISTS_OUTPUT, + QUERY_MAPS as _SCHEMA_QUERY_MAPS, + QUERY_MAPS_INPUT as _SCHEMA_QUERY_MAPS_INPUT, + QUERY_MAPS_OUTPUT as _SCHEMA_QUERY_MAPS_OUTPUT, + QUERY_TIMESTAMPS as _SCHEMA_QUERY_TIMESTAMPS, + QUERY_TIMESTAMPS_INPUT as _SCHEMA_QUERY_TIMESTAMPS_INPUT, + QUERY_TIMESTAMPS_OUTPUT as _SCHEMA_QUERY_TIMESTAMPS_OUTPUT, + RECURSIVE_XML_SHAPES as _SCHEMA_RECURSIVE_XML_SHAPES, + RECURSIVE_XML_SHAPES_INPUT as _SCHEMA_RECURSIVE_XML_SHAPES_INPUT, + RECURSIVE_XML_SHAPES_OUTPUT as _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT, + RECURSIVE_XML_SHAPES_OUTPUT_NESTED1 as _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED1, + RECURSIVE_XML_SHAPES_OUTPUT_NESTED2 as _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED2, + SIMPLE_INPUT_PARAMS as _SCHEMA_SIMPLE_INPUT_PARAMS, + SIMPLE_INPUT_PARAMS_INPUT as _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT, + SIMPLE_INPUT_PARAMS_OUTPUT as _SCHEMA_SIMPLE_INPUT_PARAMS_OUTPUT, + SIMPLE_SCALAR_XML_PROPERTIES as _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES, + SIMPLE_SCALAR_XML_PROPERTIES_INPUT as _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_INPUT, + SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT as _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT, + STRUCTURE_LIST_MEMBER as _SCHEMA_STRUCTURE_LIST_MEMBER, + STRUCT_ARG as _SCHEMA_STRUCT_ARG, + XML_BLOBS as _SCHEMA_XML_BLOBS, + XML_BLOBS_INPUT as _SCHEMA_XML_BLOBS_INPUT, + XML_BLOBS_OPERATION_OUTPUT as _SCHEMA_XML_BLOBS_OPERATION_OUTPUT, + XML_EMPTY_BLOBS as _SCHEMA_XML_EMPTY_BLOBS, + XML_EMPTY_BLOBS_INPUT as _SCHEMA_XML_EMPTY_BLOBS_INPUT, + XML_EMPTY_BLOBS_OUTPUT as _SCHEMA_XML_EMPTY_BLOBS_OUTPUT, + XML_EMPTY_LISTS as _SCHEMA_XML_EMPTY_LISTS, + XML_EMPTY_LISTS_INPUT as _SCHEMA_XML_EMPTY_LISTS_INPUT, + XML_EMPTY_LISTS_OUTPUT as _SCHEMA_XML_EMPTY_LISTS_OUTPUT, + XML_EMPTY_MAPS as _SCHEMA_XML_EMPTY_MAPS, + XML_EMPTY_MAPS_INPUT as _SCHEMA_XML_EMPTY_MAPS_INPUT, + XML_EMPTY_MAPS_OUTPUT as _SCHEMA_XML_EMPTY_MAPS_OUTPUT, + XML_ENUMS as _SCHEMA_XML_ENUMS, + XML_ENUMS_INPUT as _SCHEMA_XML_ENUMS_INPUT, + XML_ENUMS_OUTPUT as _SCHEMA_XML_ENUMS_OUTPUT, + XML_INT_ENUMS as _SCHEMA_XML_INT_ENUMS, + XML_INT_ENUMS_INPUT as _SCHEMA_XML_INT_ENUMS_INPUT, + XML_INT_ENUMS_OUTPUT as _SCHEMA_XML_INT_ENUMS_OUTPUT, + XML_LISTS as _SCHEMA_XML_LISTS, + XML_LISTS_INPUT as _SCHEMA_XML_LISTS_INPUT, + XML_LISTS_OPERATION_OUTPUT as _SCHEMA_XML_LISTS_OPERATION_OUTPUT, + XML_MAPS as _SCHEMA_XML_MAPS, + XML_MAPS_INPUT as _SCHEMA_XML_MAPS_INPUT, + XML_MAPS_OPERATION_OUTPUT as _SCHEMA_XML_MAPS_OPERATION_OUTPUT, + XML_MAPS_XML_NAME as _SCHEMA_XML_MAPS_XML_NAME, + XML_MAPS_XML_NAME_INPUT as _SCHEMA_XML_MAPS_XML_NAME_INPUT, + XML_MAPS_XML_NAME_OUTPUT as _SCHEMA_XML_MAPS_XML_NAME_OUTPUT, + XML_NAMESPACES as _SCHEMA_XML_NAMESPACES, + XML_NAMESPACES_INPUT as _SCHEMA_XML_NAMESPACES_INPUT, + XML_NAMESPACES_OUTPUT as _SCHEMA_XML_NAMESPACES_OUTPUT, + XML_NAMESPACE_NESTED as _SCHEMA_XML_NAMESPACE_NESTED, + XML_TIMESTAMPS as _SCHEMA_XML_TIMESTAMPS, + XML_TIMESTAMPS_INPUT as _SCHEMA_XML_TIMESTAMPS_INPUT, + XML_TIMESTAMPS_OUTPUT as _SCHEMA_XML_TIMESTAMPS_OUTPUT, +) + + +logger = logging.getLogger(__name__) + + +class ServiceError(ModeledError): + """ + Base error for all errors in the service. + + Some exceptions do not extend from this class, including + synthetic, implicit, and shared exception types. + """ + + +@dataclass(kw_only=True) +class DatetimeOffsetsInput: + """Dataclass for DatetimeOffsetsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DATETIME_OFFSETS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DATETIME_OFFSETS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class DatetimeOffsetsOutput: + """Dataclass for DatetimeOffsetsOutput structure.""" + + datetime_: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DATETIME_OFFSETS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.datetime_ is not None: + serializer.write_timestamp( + _SCHEMA_DATETIME_OFFSETS_OUTPUT.members["datetime"], self.datetime_ + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["datetime_"] = de.read_timestamp( + _SCHEMA_DATETIME_OFFSETS_OUTPUT.members["datetime"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DATETIME_OFFSETS_OUTPUT, consumer=_consumer) + return kwargs + + +DATETIME_OFFSETS = APIOperation( + input=DatetimeOffsetsInput, + output=DatetimeOffsetsOutput, + schema=_SCHEMA_DATETIME_OFFSETS, + input_schema=_SCHEMA_DATETIME_OFFSETS_INPUT, + output_schema=_SCHEMA_DATETIME_OFFSETS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EmptyInputAndEmptyOutputInput: + """Dataclass for EmptyInputAndEmptyOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class EmptyInputAndEmptyOutputOutput: + """Dataclass for EmptyInputAndEmptyOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, consumer=_consumer + ) + return kwargs + + +EMPTY_INPUT_AND_EMPTY_OUTPUT = APIOperation( + input=EmptyInputAndEmptyOutputInput, + output=EmptyInputAndEmptyOutputOutput, + schema=_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT, + input_schema=_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, + output_schema=_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EndpointOperationInput: + """Dataclass for EndpointOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ENDPOINT_OPERATION_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class EndpointOperationOutput: + """Dataclass for EndpointOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ENDPOINT_OPERATION_OUTPUT, consumer=_consumer) + return kwargs + + +ENDPOINT_OPERATION = APIOperation( + input=EndpointOperationInput, + output=EndpointOperationOutput, + schema=_SCHEMA_ENDPOINT_OPERATION, + input_schema=_SCHEMA_ENDPOINT_OPERATION_INPUT, + output_schema=_SCHEMA_ENDPOINT_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EndpointWithHostLabelOperationInput: + """Dataclass for EndpointWithHostLabelOperationInput structure.""" + + label: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.label is not None: + serializer.write_string( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT.members["label"], + self.label, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["label"] = de.read_string( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT.members[ + "label" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class EndpointWithHostLabelOperationOutput: + """Dataclass for EndpointWithHostLabelOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +ENDPOINT_WITH_HOST_LABEL_OPERATION = APIOperation( + input=EndpointWithHostLabelOperationInput, + output=EndpointWithHostLabelOperationOutput, + schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION, + input_schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, + output_schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class FlattenedXmlMapInput: + """Dataclass for FlattenedXmlMapInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FLATTENED_XML_MAP_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FLATTENED_XML_MAP_INPUT, consumer=_consumer) + return kwargs + + +class FooEnum(UnknownEnumMixin, StrEnum): + FOO = "Foo" + BAZ = "Baz" + BAR = "Bar" + ONE = "1" + ZERO = "0" + + +def _serialize_foo_enum_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_foo_enum_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = FooEnum(d.read_string(value_schema)) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class FlattenedXmlMapOutput: + """Dataclass for FlattenedXmlMapOutput structure.""" + + my_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FLATTENED_XML_MAP_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.my_map is not None: + _serialize_foo_enum_map( + serializer, + _SCHEMA_FLATTENED_XML_MAP_OUTPUT.members["myMap"], + self.my_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["my_map"] = _deserialize_foo_enum_map( + de, _SCHEMA_FLATTENED_XML_MAP_OUTPUT.members["myMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FLATTENED_XML_MAP_OUTPUT, consumer=_consumer) + return kwargs + + +FLATTENED_XML_MAP = APIOperation( + input=FlattenedXmlMapInput, + output=FlattenedXmlMapOutput, + schema=_SCHEMA_FLATTENED_XML_MAP, + input_schema=_SCHEMA_FLATTENED_XML_MAP_INPUT, + output_schema=_SCHEMA_FLATTENED_XML_MAP_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class FlattenedXmlMapWithXmlNameInput: + """Dataclass for FlattenedXmlMapWithXmlNameInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_INPUT, consumer=_consumer + ) + return kwargs + + +def _serialize_flattened_xml_map_with_xml_name_output_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_flattened_xml_map_with_xml_name_output_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class FlattenedXmlMapWithXmlNameOutput: + """Dataclass for FlattenedXmlMapWithXmlNameOutput structure.""" + + my_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.my_map is not None: + _serialize_flattened_xml_map_with_xml_name_output_map( + serializer, + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT.members["myMap"], + self.my_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["my_map"] = ( + _deserialize_flattened_xml_map_with_xml_name_output_map( + de, + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT.members[ + "myMap" + ], + ) + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT, consumer=_consumer + ) + return kwargs + + +FLATTENED_XML_MAP_WITH_XML_NAME = APIOperation( + input=FlattenedXmlMapWithXmlNameInput, + output=FlattenedXmlMapWithXmlNameOutput, + schema=_SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME, + input_schema=_SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_INPUT, + output_schema=_SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAME_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class FlattenedXmlMapWithXmlNamespaceInput: + """Dataclass for FlattenedXmlMapWithXmlNamespaceInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_INPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_INPUT, consumer=_consumer + ) + return kwargs + + +def _serialize_flattened_xml_map_with_xml_namespace_output_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_flattened_xml_map_with_xml_namespace_output_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class FlattenedXmlMapWithXmlNamespaceOutput: + """Dataclass for FlattenedXmlMapWithXmlNamespaceOutput structure.""" + + my_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.my_map is not None: + _serialize_flattened_xml_map_with_xml_namespace_output_map( + serializer, + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT.members["myMap"], + self.my_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["my_map"] = ( + _deserialize_flattened_xml_map_with_xml_namespace_output_map( + de, + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT.members[ + "myMap" + ], + ) + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT, consumer=_consumer + ) + return kwargs + + +FLATTENED_XML_MAP_WITH_XML_NAMESPACE = APIOperation( + input=FlattenedXmlMapWithXmlNamespaceInput, + output=FlattenedXmlMapWithXmlNamespaceOutput, + schema=_SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE, + input_schema=_SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_INPUT, + output_schema=_SCHEMA_FLATTENED_XML_MAP_WITH_XML_NAMESPACE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class FractionalSecondsInput: + """Dataclass for FractionalSecondsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FRACTIONAL_SECONDS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FRACTIONAL_SECONDS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class FractionalSecondsOutput: + """Dataclass for FractionalSecondsOutput structure.""" + + datetime_: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FRACTIONAL_SECONDS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.datetime_ is not None: + serializer.write_timestamp( + _SCHEMA_FRACTIONAL_SECONDS_OUTPUT.members["datetime"], self.datetime_ + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["datetime_"] = de.read_timestamp( + _SCHEMA_FRACTIONAL_SECONDS_OUTPUT.members["datetime"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FRACTIONAL_SECONDS_OUTPUT, consumer=_consumer) + return kwargs + + +FRACTIONAL_SECONDS = APIOperation( + input=FractionalSecondsInput, + output=FractionalSecondsOutput, + schema=_SCHEMA_FRACTIONAL_SECONDS, + input_schema=_SCHEMA_FRACTIONAL_SECONDS_INPUT, + output_schema=_SCHEMA_FRACTIONAL_SECONDS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class ComplexNestedErrorData: + """Dataclass for ComplexNestedErrorData structure.""" + + foo: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_COMPLEX_NESTED_ERROR_DATA, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_COMPLEX_NESTED_ERROR_DATA.members["Foo"], self.foo + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_COMPLEX_NESTED_ERROR_DATA.members["Foo"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_COMPLEX_NESTED_ERROR_DATA, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ComplexError(ServiceError): + """This error is thrown when a request is invalid.""" + + fault: Literal["client", "server"] | None = "client" + + top_level: str | None = None + + nested: ComplexNestedErrorData | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_COMPLEX_ERROR, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.top_level is not None: + serializer.write_string( + _SCHEMA_COMPLEX_ERROR.members["TopLevel"], self.top_level + ) + + if self.nested is not None: + serializer.write_struct( + _SCHEMA_COMPLEX_ERROR.members["Nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["top_level"] = de.read_string( + _SCHEMA_COMPLEX_ERROR.members["TopLevel"] + ) + + case 1: + kwargs["nested"] = ComplexNestedErrorData.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_COMPLEX_ERROR, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class CustomCodeError(ServiceError): + """Dataclass for CustomCodeError structure.""" + + fault: Literal["client", "server"] | None = "client" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CUSTOM_CODE_ERROR, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.message is not None: + serializer.write_string( + _SCHEMA_CUSTOM_CODE_ERROR.members["Message"], self.message + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["message"] = de.read_string( + _SCHEMA_CUSTOM_CODE_ERROR.members["Message"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_CUSTOM_CODE_ERROR, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class GreetingWithErrorsInput: + """Dataclass for GreetingWithErrorsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_WITH_ERRORS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_GREETING_WITH_ERRORS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class GreetingWithErrorsOutput: + """Dataclass for GreetingWithErrorsOutput structure.""" + + greeting: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_WITH_ERRORS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.greeting is not None: + serializer.write_string( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT.members["greeting"], self.greeting + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["greeting"] = de.read_string( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT.members["greeting"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class InvalidGreeting(ServiceError): + """This error is thrown when an invalid greeting value is provided.""" + + fault: Literal["client", "server"] | None = "client" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INVALID_GREETING, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.message is not None: + serializer.write_string( + _SCHEMA_INVALID_GREETING.members["Message"], self.message + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["message"] = de.read_string( + _SCHEMA_INVALID_GREETING.members["Message"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_INVALID_GREETING, consumer=_consumer) + return kwargs + + +GREETING_WITH_ERRORS = APIOperation( + input=GreetingWithErrorsInput, + output=GreetingWithErrorsOutput, + schema=_SCHEMA_GREETING_WITH_ERRORS, + input_schema=_SCHEMA_GREETING_WITH_ERRORS_INPUT, + output_schema=_SCHEMA_GREETING_WITH_ERRORS_OUTPUT, + error_registry=TypeRegistry( + { + ShapeID("aws.protocoltests.query#InvalidGreeting"): InvalidGreeting, + ShapeID("aws.protocoltests.query#ComplexError"): ComplexError, + ShapeID("aws.protocoltests.query#CustomCodeError"): CustomCodeError, + } + ), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[ + _SCHEMA_INVALID_GREETING, + _SCHEMA_COMPLEX_ERROR, + _SCHEMA_CUSTOM_CODE_ERROR, + ], +) + + +@dataclass(kw_only=True) +class HostWithPathOperationInput: + """Dataclass for HostWithPathOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HostWithPathOperationOutput: + """Dataclass for HostWithPathOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +HOST_WITH_PATH_OPERATION = APIOperation( + input=HostWithPathOperationInput, + output=HostWithPathOperationOutput, + schema=_SCHEMA_HOST_WITH_PATH_OPERATION, + input_schema=_SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, + output_schema=_SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class IgnoresWrappingXmlNameInput: + """Dataclass for IgnoresWrappingXmlNameInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_IGNORES_WRAPPING_XML_NAME_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_IGNORES_WRAPPING_XML_NAME_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class IgnoresWrappingXmlNameOutput: + """Dataclass for IgnoresWrappingXmlNameOutput structure.""" + + foo: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_IGNORES_WRAPPING_XML_NAME_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_IGNORES_WRAPPING_XML_NAME_OUTPUT.members["foo"], self.foo + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_IGNORES_WRAPPING_XML_NAME_OUTPUT.members["foo"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_IGNORES_WRAPPING_XML_NAME_OUTPUT, consumer=_consumer + ) + return kwargs + + +IGNORES_WRAPPING_XML_NAME = APIOperation( + input=IgnoresWrappingXmlNameInput, + output=IgnoresWrappingXmlNameOutput, + schema=_SCHEMA_IGNORES_WRAPPING_XML_NAME, + input_schema=_SCHEMA_IGNORES_WRAPPING_XML_NAME_INPUT, + output_schema=_SCHEMA_IGNORES_WRAPPING_XML_NAME_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NestedStructuresOutput: + """Dataclass for NestedStructuresOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NESTED_STRUCTURES_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NESTED_STRUCTURES_OUTPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class NoInputAndNoOutputInput: + """Dataclass for NoInputAndNoOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class NoInputAndNoOutputOutput: + """Dataclass for NoInputAndNoOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, consumer=_consumer + ) + return kwargs + + +NO_INPUT_AND_NO_OUTPUT = APIOperation( + input=NoInputAndNoOutputInput, + output=NoInputAndNoOutputOutput, + schema=_SCHEMA_NO_INPUT_AND_NO_OUTPUT, + input_schema=_SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, + output_schema=_SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NoInputAndOutputInput: + """Dataclass for NoInputAndOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class NoInputAndOutputOutput: + """Dataclass for NoInputAndOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, consumer=_consumer) + return kwargs + + +NO_INPUT_AND_OUTPUT = APIOperation( + input=NoInputAndOutputInput, + output=NoInputAndOutputOutput, + schema=_SCHEMA_NO_INPUT_AND_OUTPUT, + input_schema=_SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, + output_schema=_SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class PutWithContentEncodingInput: + """Dataclass for PutWithContentEncodingInput structure.""" + + encoding: str | None = None + + data: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.encoding is not None: + serializer.write_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["encoding"], + self.encoding, + ) + + if self.data is not None: + serializer.write_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["data"], self.data + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["encoding"] = de.read_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["encoding"] + ) + + case 1: + kwargs["data"] = de.read_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class PutWithContentEncodingOutput: + """Dataclass for PutWithContentEncodingOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, consumer=_consumer + ) + return kwargs + + +PUT_WITH_CONTENT_ENCODING = APIOperation( + input=PutWithContentEncodingInput, + output=PutWithContentEncodingOutput, + schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING, + input_schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, + output_schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class QueryIdempotencyTokenAutoFillInput: + """Dataclass for QueryIdempotencyTokenAutoFillInput structure.""" + + token: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.token is not None: + serializer.write_string( + _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT.members["token"], + self.token, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["token"] = de.read_string( + _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT.members["token"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class QueryIdempotencyTokenAutoFillOutput: + """Dataclass for QueryIdempotencyTokenAutoFillOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT, consumer=_consumer + ) + return kwargs + + +QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL = APIOperation( + input=QueryIdempotencyTokenAutoFillInput, + output=QueryIdempotencyTokenAutoFillOutput, + schema=_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL, + input_schema=_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT, + output_schema=_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class GreetingStruct: + """Dataclass for GreetingStruct structure.""" + + hi: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_STRUCT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.hi is not None: + serializer.write_string(_SCHEMA_GREETING_STRUCT.members["hi"], self.hi) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["hi"] = de.read_string(_SCHEMA_GREETING_STRUCT.members["hi"]) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_GREETING_STRUCT, consumer=_consumer) + return kwargs + + +def _serialize_greeting_list( + serializer: ShapeSerializer, schema: Schema, value: list[GreetingStruct] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_struct(member_schema, e) + + +def _deserialize_greeting_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[GreetingStruct]: + result: list[GreetingStruct] = [] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(GreetingStruct.deserialize(d)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_list_with_xml_name( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_list_with_xml_name( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class NestedStructWithList: + """Dataclass for NestedStructWithList structure.""" + + list_arg: list[str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NESTED_STRUCT_WITH_LIST, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.list_arg is not None: + _serialize_string_list( + serializer, + _SCHEMA_NESTED_STRUCT_WITH_LIST.members["ListArg"], + self.list_arg, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["list_arg"] = _deserialize_string_list( + de, _SCHEMA_NESTED_STRUCT_WITH_LIST.members["ListArg"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NESTED_STRUCT_WITH_LIST, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class QueryListsInput: + """Dataclass for QueryListsInput structure.""" + + list_arg: list[str] | None = None + + complex_list_arg: list[GreetingStruct] | None = None + + flattened_list_arg: list[str] | None = None + + list_arg_with_xml_name_member: list[str] | None = None + + flattened_list_arg_with_xml_name: list[str] | None = None + + nested_with_list: NestedStructWithList | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_LISTS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.list_arg is not None: + _serialize_string_list( + serializer, _SCHEMA_QUERY_LISTS_INPUT.members["ListArg"], self.list_arg + ) + + if self.complex_list_arg is not None: + _serialize_greeting_list( + serializer, + _SCHEMA_QUERY_LISTS_INPUT.members["ComplexListArg"], + self.complex_list_arg, + ) + + if self.flattened_list_arg is not None: + _serialize_string_list( + serializer, + _SCHEMA_QUERY_LISTS_INPUT.members["FlattenedListArg"], + self.flattened_list_arg, + ) + + if self.list_arg_with_xml_name_member is not None: + _serialize_list_with_xml_name( + serializer, + _SCHEMA_QUERY_LISTS_INPUT.members["ListArgWithXmlNameMember"], + self.list_arg_with_xml_name_member, + ) + + if self.flattened_list_arg_with_xml_name is not None: + _serialize_list_with_xml_name( + serializer, + _SCHEMA_QUERY_LISTS_INPUT.members["FlattenedListArgWithXmlName"], + self.flattened_list_arg_with_xml_name, + ) + + if self.nested_with_list is not None: + serializer.write_struct( + _SCHEMA_QUERY_LISTS_INPUT.members["NestedWithList"], + self.nested_with_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["list_arg"] = _deserialize_string_list( + de, _SCHEMA_QUERY_LISTS_INPUT.members["ListArg"] + ) + + case 1: + kwargs["complex_list_arg"] = _deserialize_greeting_list( + de, _SCHEMA_QUERY_LISTS_INPUT.members["ComplexListArg"] + ) + + case 2: + kwargs["flattened_list_arg"] = _deserialize_string_list( + de, _SCHEMA_QUERY_LISTS_INPUT.members["FlattenedListArg"] + ) + + case 3: + kwargs["list_arg_with_xml_name_member"] = ( + _deserialize_list_with_xml_name( + de, + _SCHEMA_QUERY_LISTS_INPUT.members[ + "ListArgWithXmlNameMember" + ], + ) + ) + + case 4: + kwargs["flattened_list_arg_with_xml_name"] = ( + _deserialize_list_with_xml_name( + de, + _SCHEMA_QUERY_LISTS_INPUT.members[ + "FlattenedListArgWithXmlName" + ], + ) + ) + + case 5: + kwargs["nested_with_list"] = NestedStructWithList.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_QUERY_LISTS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class QueryListsOutput: + """Dataclass for QueryListsOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_LISTS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_QUERY_LISTS_OUTPUT, consumer=_consumer) + return kwargs + + +QUERY_LISTS = APIOperation( + input=QueryListsInput, + output=QueryListsOutput, + schema=_SCHEMA_QUERY_LISTS, + input_schema=_SCHEMA_QUERY_LISTS_INPUT, + output_schema=_SCHEMA_QUERY_LISTS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_complex_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, GreetingStruct] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_struct(value_schema, v)) + + +def _deserialize_complex_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, GreetingStruct]: + result: dict[str, GreetingStruct] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = GreetingStruct.deserialize(d) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_map_with_xml_name( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_map_with_xml_name( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_map_of_lists( + serializer: ShapeSerializer, schema: Schema, value: dict[str, list[str]] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: _serialize_string_list(vs, value_schema, v)) + + +def _deserialize_map_of_lists( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, list[str]]: + result: dict[str, list[str]] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = _deserialize_string_list(d, value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class NestedStructWithMap: + """Dataclass for NestedStructWithMap structure.""" + + map_arg: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NESTED_STRUCT_WITH_MAP, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.map_arg is not None: + _serialize_string_map( + serializer, + _SCHEMA_NESTED_STRUCT_WITH_MAP.members["MapArg"], + self.map_arg, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["map_arg"] = _deserialize_string_map( + de, _SCHEMA_NESTED_STRUCT_WITH_MAP.members["MapArg"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NESTED_STRUCT_WITH_MAP, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class QueryMapsInput: + """Dataclass for QueryMapsInput structure.""" + + map_arg: dict[str, str] | None = None + + renamed_map_arg: dict[str, str] | None = None + + complex_map_arg: dict[str, GreetingStruct] | None = None + + map_with_xml_member_name: dict[str, str] | None = None + + flattened_map: dict[str, str] | None = None + + flattened_map_with_xml_name: dict[str, str] | None = None + + map_of_lists: dict[str, list[str]] | None = None + + nested_struct_with_map: NestedStructWithMap | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_MAPS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.map_arg is not None: + _serialize_string_map( + serializer, _SCHEMA_QUERY_MAPS_INPUT.members["MapArg"], self.map_arg + ) + + if self.renamed_map_arg is not None: + _serialize_string_map( + serializer, + _SCHEMA_QUERY_MAPS_INPUT.members["RenamedMapArg"], + self.renamed_map_arg, + ) + + if self.complex_map_arg is not None: + _serialize_complex_map( + serializer, + _SCHEMA_QUERY_MAPS_INPUT.members["ComplexMapArg"], + self.complex_map_arg, + ) + + if self.map_with_xml_member_name is not None: + _serialize_map_with_xml_name( + serializer, + _SCHEMA_QUERY_MAPS_INPUT.members["MapWithXmlMemberName"], + self.map_with_xml_member_name, + ) + + if self.flattened_map is not None: + _serialize_string_map( + serializer, + _SCHEMA_QUERY_MAPS_INPUT.members["FlattenedMap"], + self.flattened_map, + ) + + if self.flattened_map_with_xml_name is not None: + _serialize_map_with_xml_name( + serializer, + _SCHEMA_QUERY_MAPS_INPUT.members["FlattenedMapWithXmlName"], + self.flattened_map_with_xml_name, + ) + + if self.map_of_lists is not None: + _serialize_map_of_lists( + serializer, + _SCHEMA_QUERY_MAPS_INPUT.members["MapOfLists"], + self.map_of_lists, + ) + + if self.nested_struct_with_map is not None: + serializer.write_struct( + _SCHEMA_QUERY_MAPS_INPUT.members["NestedStructWithMap"], + self.nested_struct_with_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["map_arg"] = _deserialize_string_map( + de, _SCHEMA_QUERY_MAPS_INPUT.members["MapArg"] + ) + + case 1: + kwargs["renamed_map_arg"] = _deserialize_string_map( + de, _SCHEMA_QUERY_MAPS_INPUT.members["RenamedMapArg"] + ) + + case 2: + kwargs["complex_map_arg"] = _deserialize_complex_map( + de, _SCHEMA_QUERY_MAPS_INPUT.members["ComplexMapArg"] + ) + + case 3: + kwargs["map_with_xml_member_name"] = _deserialize_map_with_xml_name( + de, _SCHEMA_QUERY_MAPS_INPUT.members["MapWithXmlMemberName"] + ) + + case 4: + kwargs["flattened_map"] = _deserialize_string_map( + de, _SCHEMA_QUERY_MAPS_INPUT.members["FlattenedMap"] + ) + + case 5: + kwargs["flattened_map_with_xml_name"] = ( + _deserialize_map_with_xml_name( + de, + _SCHEMA_QUERY_MAPS_INPUT.members["FlattenedMapWithXmlName"], + ) + ) + + case 6: + kwargs["map_of_lists"] = _deserialize_map_of_lists( + de, _SCHEMA_QUERY_MAPS_INPUT.members["MapOfLists"] + ) + + case 7: + kwargs["nested_struct_with_map"] = NestedStructWithMap.deserialize( + de + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_QUERY_MAPS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class QueryMapsOutput: + """Dataclass for QueryMapsOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_MAPS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_QUERY_MAPS_OUTPUT, consumer=_consumer) + return kwargs + + +QUERY_MAPS = APIOperation( + input=QueryMapsInput, + output=QueryMapsOutput, + schema=_SCHEMA_QUERY_MAPS, + input_schema=_SCHEMA_QUERY_MAPS_INPUT, + output_schema=_SCHEMA_QUERY_MAPS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class QueryTimestampsInput: + """Dataclass for QueryTimestampsInput structure.""" + + normal_format: datetime | None = None + + epoch_member: datetime | None = None + + epoch_target: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_TIMESTAMPS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.normal_format is not None: + serializer.write_timestamp( + _SCHEMA_QUERY_TIMESTAMPS_INPUT.members["normalFormat"], + self.normal_format, + ) + + if self.epoch_member is not None: + serializer.write_timestamp( + _SCHEMA_QUERY_TIMESTAMPS_INPUT.members["epochMember"], self.epoch_member + ) + + if self.epoch_target is not None: + serializer.write_timestamp( + _SCHEMA_QUERY_TIMESTAMPS_INPUT.members["epochTarget"], self.epoch_target + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["normal_format"] = de.read_timestamp( + _SCHEMA_QUERY_TIMESTAMPS_INPUT.members["normalFormat"] + ) + + case 1: + kwargs["epoch_member"] = de.read_timestamp( + _SCHEMA_QUERY_TIMESTAMPS_INPUT.members["epochMember"] + ) + + case 2: + kwargs["epoch_target"] = de.read_timestamp( + _SCHEMA_QUERY_TIMESTAMPS_INPUT.members["epochTarget"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_QUERY_TIMESTAMPS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class QueryTimestampsOutput: + """Dataclass for QueryTimestampsOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_TIMESTAMPS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_QUERY_TIMESTAMPS_OUTPUT, consumer=_consumer) + return kwargs + + +QUERY_TIMESTAMPS = APIOperation( + input=QueryTimestampsInput, + output=QueryTimestampsOutput, + schema=_SCHEMA_QUERY_TIMESTAMPS, + input_schema=_SCHEMA_QUERY_TIMESTAMPS_INPUT, + output_schema=_SCHEMA_QUERY_TIMESTAMPS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class RecursiveXmlShapesInput: + """Dataclass for RecursiveXmlShapesInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RECURSIVE_XML_SHAPES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_RECURSIVE_XML_SHAPES_INPUT, consumer=_consumer) + return kwargs + + +class IntegerEnum(UnknownEnumMixin, IntEnum): + A = 1 + B = 2 + C = 3 + + +@dataclass(kw_only=True) +class SimpleInputParamsInput: + """Dataclass for SimpleInputParamsInput structure.""" + + foo: str | None = None + + bar: str | None = None + + baz: bool | None = None + + bam: int | None = None + + float_value: float | None = None + + boo: float | None = None + + qux: bytes | None = None + + foo_enum: str | None = None + + integer_enum: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_INPUT_PARAMS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Foo"], self.foo + ) + + if self.bar is not None: + serializer.write_string( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Bar"], self.bar + ) + + if self.baz is not None: + serializer.write_boolean( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Baz"], self.baz + ) + + if self.bam is not None: + serializer.write_integer( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Bam"], self.bam + ) + + if self.float_value is not None: + serializer.write_float( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["FloatValue"], + self.float_value, + ) + + if self.boo is not None: + serializer.write_double( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Boo"], self.boo + ) + + if self.qux is not None: + serializer.write_blob( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Qux"], self.qux + ) + + if self.foo_enum is not None: + serializer.write_string( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["FooEnum"], self.foo_enum + ) + + if self.integer_enum is not None: + serializer.write_integer( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["IntegerEnum"], + self.integer_enum, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Foo"] + ) + + case 1: + kwargs["bar"] = de.read_string( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Bar"] + ) + + case 2: + kwargs["baz"] = de.read_boolean( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Baz"] + ) + + case 3: + kwargs["bam"] = de.read_integer( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Bam"] + ) + + case 4: + kwargs["float_value"] = de.read_float( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["FloatValue"] + ) + + case 5: + kwargs["boo"] = de.read_double( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Boo"] + ) + + case 6: + kwargs["qux"] = de.read_blob( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["Qux"] + ) + + case 7: + kwargs["foo_enum"] = FooEnum( + de.read_string( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["FooEnum"] + ) + ) + + case 8: + kwargs["integer_enum"] = IntegerEnum( + de.read_integer( + _SCHEMA_SIMPLE_INPUT_PARAMS_INPUT.members["IntegerEnum"] + ) + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_SIMPLE_INPUT_PARAMS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class SimpleInputParamsOutput: + """Dataclass for SimpleInputParamsOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_INPUT_PARAMS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_SIMPLE_INPUT_PARAMS_OUTPUT, consumer=_consumer) + return kwargs + + +SIMPLE_INPUT_PARAMS = APIOperation( + input=SimpleInputParamsInput, + output=SimpleInputParamsOutput, + schema=_SCHEMA_SIMPLE_INPUT_PARAMS, + input_schema=_SCHEMA_SIMPLE_INPUT_PARAMS_INPUT, + output_schema=_SCHEMA_SIMPLE_INPUT_PARAMS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class SimpleScalarXmlPropertiesInput: + """Dataclass for SimpleScalarXmlPropertiesInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class SimpleScalarXmlPropertiesOutput: + """Dataclass for SimpleScalarXmlPropertiesOutput structure.""" + + string_value: str | None = None + + empty_string_value: str | None = None + + true_boolean_value: bool | None = None + + false_boolean_value: bool | None = None + + byte_value: int | None = None + + short_value: int | None = None + + integer_value: int | None = None + + long_value: int | None = None + + float_value: float | None = None + + double_value: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string_value is not None: + serializer.write_string( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["stringValue"], + self.string_value, + ) + + if self.empty_string_value is not None: + serializer.write_string( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["emptyStringValue"], + self.empty_string_value, + ) + + if self.true_boolean_value is not None: + serializer.write_boolean( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["trueBooleanValue"], + self.true_boolean_value, + ) + + if self.false_boolean_value is not None: + serializer.write_boolean( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members[ + "falseBooleanValue" + ], + self.false_boolean_value, + ) + + if self.byte_value is not None: + serializer.write_byte( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["byteValue"], + self.byte_value, + ) + + if self.short_value is not None: + serializer.write_short( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["shortValue"], + self.short_value, + ) + + if self.integer_value is not None: + serializer.write_integer( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["integerValue"], + self.integer_value, + ) + + if self.long_value is not None: + serializer.write_long( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["longValue"], + self.long_value, + ) + + if self.float_value is not None: + serializer.write_float( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["floatValue"], + self.float_value, + ) + + if self.double_value is not None: + serializer.write_double( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["doubleValue"], + self.double_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string_value"] = de.read_string( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members[ + "stringValue" + ] + ) + + case 1: + kwargs["empty_string_value"] = de.read_string( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members[ + "emptyStringValue" + ] + ) + + case 2: + kwargs["true_boolean_value"] = de.read_boolean( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members[ + "trueBooleanValue" + ] + ) + + case 3: + kwargs["false_boolean_value"] = de.read_boolean( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members[ + "falseBooleanValue" + ] + ) + + case 4: + kwargs["byte_value"] = de.read_byte( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["byteValue"] + ) + + case 5: + kwargs["short_value"] = de.read_short( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members[ + "shortValue" + ] + ) + + case 6: + kwargs["integer_value"] = de.read_integer( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members[ + "integerValue" + ] + ) + + case 7: + kwargs["long_value"] = de.read_long( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members["longValue"] + ) + + case 8: + kwargs["float_value"] = de.read_float( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members[ + "floatValue" + ] + ) + + case 9: + kwargs["double_value"] = de.read_double( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT.members[ + "doubleValue" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT, consumer=_consumer + ) + return kwargs + + +SIMPLE_SCALAR_XML_PROPERTIES = APIOperation( + input=SimpleScalarXmlPropertiesInput, + output=SimpleScalarXmlPropertiesOutput, + schema=_SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES, + input_schema=_SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_INPUT, + output_schema=_SCHEMA_SIMPLE_SCALAR_XML_PROPERTIES_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlBlobsInput: + """Dataclass for XmlBlobsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_BLOBS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_BLOBS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class XmlBlobsOperationOutput: + """Dataclass for XmlBlobsOperationOutput structure.""" + + data: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_BLOBS_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.data is not None: + serializer.write_blob( + _SCHEMA_XML_BLOBS_OPERATION_OUTPUT.members["data"], self.data + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["data"] = de.read_blob( + _SCHEMA_XML_BLOBS_OPERATION_OUTPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_BLOBS_OPERATION_OUTPUT, consumer=_consumer) + return kwargs + + +XML_BLOBS = APIOperation( + input=XmlBlobsInput, + output=XmlBlobsOperationOutput, + schema=_SCHEMA_XML_BLOBS, + input_schema=_SCHEMA_XML_BLOBS_INPUT, + output_schema=_SCHEMA_XML_BLOBS_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlEmptyBlobsInput: + """Dataclass for XmlEmptyBlobsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_EMPTY_BLOBS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_EMPTY_BLOBS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class XmlEmptyBlobsOutput: + """Dataclass for XmlEmptyBlobsOutput structure.""" + + data: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_EMPTY_BLOBS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.data is not None: + serializer.write_blob( + _SCHEMA_XML_EMPTY_BLOBS_OUTPUT.members["data"], self.data + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["data"] = de.read_blob( + _SCHEMA_XML_EMPTY_BLOBS_OUTPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_EMPTY_BLOBS_OUTPUT, consumer=_consumer) + return kwargs + + +XML_EMPTY_BLOBS = APIOperation( + input=XmlEmptyBlobsInput, + output=XmlEmptyBlobsOutput, + schema=_SCHEMA_XML_EMPTY_BLOBS, + input_schema=_SCHEMA_XML_EMPTY_BLOBS_INPUT, + output_schema=_SCHEMA_XML_EMPTY_BLOBS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlEmptyListsInput: + """Dataclass for XmlEmptyListsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_EMPTY_LISTS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_EMPTY_LISTS_INPUT, consumer=_consumer) + return kwargs + + +def _serialize_boolean_list( + serializer: ShapeSerializer, schema: Schema, value: list[bool] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_boolean(member_schema, e) + + +def _deserialize_boolean_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[bool]: + result: list[bool] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_boolean(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_foo_enum_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_foo_enum_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(FooEnum(d.read_string(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_renamed_list_members( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_renamed_list_members( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_list_with_member_namespace( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_list_with_member_namespace( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_list_with_namespace( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_list_with_namespace( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_integer_list( + serializer: ShapeSerializer, schema: Schema, value: list[int] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_integer(member_schema, e) + + +def _deserialize_integer_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int]: + result: list[int] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_integer(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_integer_enum_list( + serializer: ShapeSerializer, schema: Schema, value: list[int] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_integer(member_schema, e) + + +def _deserialize_integer_enum_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int]: + result: list[int] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(IntegerEnum(d.read_integer(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_nested_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[list[str]] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + _serialize_string_list(ls, member_schema, e) + + +def _deserialize_nested_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[list[str]]: + result: list[list[str]] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(_deserialize_string_list(d, member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_string_set( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_string_set( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class StructureListMember: + """Dataclass for StructureListMember structure.""" + + a: str | None = None + + b: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STRUCTURE_LIST_MEMBER, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.a is not None: + serializer.write_string(_SCHEMA_STRUCTURE_LIST_MEMBER.members["a"], self.a) + + if self.b is not None: + serializer.write_string(_SCHEMA_STRUCTURE_LIST_MEMBER.members["b"], self.b) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["a"] = de.read_string( + _SCHEMA_STRUCTURE_LIST_MEMBER.members["a"] + ) + + case 1: + kwargs["b"] = de.read_string( + _SCHEMA_STRUCTURE_LIST_MEMBER.members["b"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_STRUCTURE_LIST_MEMBER, consumer=_consumer) + return kwargs + + +def _serialize_structure_list( + serializer: ShapeSerializer, schema: Schema, value: list[StructureListMember] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_struct(member_schema, e) + + +def _deserialize_structure_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[StructureListMember]: + result: list[StructureListMember] = [] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(StructureListMember.deserialize(d)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_timestamp_list( + serializer: ShapeSerializer, schema: Schema, value: list[datetime] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_timestamp(member_schema, e) + + +def _deserialize_timestamp_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[datetime]: + result: list[datetime] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_timestamp(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class XmlEmptyListsOutput: + """Dataclass for XmlEmptyListsOutput structure.""" + + string_list: list[str] | None = None + + string_set: list[str] | None = None + + integer_list: list[int] | None = None + + boolean_list: list[bool] | None = None + + timestamp_list: list[datetime] | None = None + + enum_list: list[str] | None = None + + int_enum_list: list[int] | None = None + + nested_string_list: list[list[str]] | None = None + """A list of lists of strings.""" + + renamed_list_members: list[str] | None = None + + flattened_list: list[str] | None = None + + flattened_list2: list[str] | None = None + + flattened_list_with_member_namespace: list[str] | None = None + + flattened_list_with_namespace: list[str] | None = None + + structure_list: list[StructureListMember] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_EMPTY_LISTS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string_list is not None: + _serialize_string_list( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["stringList"], + self.string_list, + ) + + if self.string_set is not None: + _serialize_string_set( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["stringSet"], + self.string_set, + ) + + if self.integer_list is not None: + _serialize_integer_list( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["integerList"], + self.integer_list, + ) + + if self.boolean_list is not None: + _serialize_boolean_list( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["booleanList"], + self.boolean_list, + ) + + if self.timestamp_list is not None: + _serialize_timestamp_list( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["timestampList"], + self.timestamp_list, + ) + + if self.enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["enumList"], + self.enum_list, + ) + + if self.int_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["intEnumList"], + self.int_enum_list, + ) + + if self.nested_string_list is not None: + _serialize_nested_string_list( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["nestedStringList"], + self.nested_string_list, + ) + + if self.renamed_list_members is not None: + _serialize_renamed_list_members( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["renamedListMembers"], + self.renamed_list_members, + ) + + if self.flattened_list is not None: + _serialize_renamed_list_members( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["flattenedList"], + self.flattened_list, + ) + + if self.flattened_list2 is not None: + _serialize_renamed_list_members( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["flattenedList2"], + self.flattened_list2, + ) + + if self.flattened_list_with_member_namespace is not None: + _serialize_list_with_member_namespace( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members[ + "flattenedListWithMemberNamespace" + ], + self.flattened_list_with_member_namespace, + ) + + if self.flattened_list_with_namespace is not None: + _serialize_list_with_namespace( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["flattenedListWithNamespace"], + self.flattened_list_with_namespace, + ) + + if self.structure_list is not None: + _serialize_structure_list( + serializer, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["structureList"], + self.structure_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string_list"] = _deserialize_string_list( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["stringList"] + ) + + case 1: + kwargs["string_set"] = _deserialize_string_set( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["stringSet"] + ) + + case 2: + kwargs["integer_list"] = _deserialize_integer_list( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["integerList"] + ) + + case 3: + kwargs["boolean_list"] = _deserialize_boolean_list( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["booleanList"] + ) + + case 4: + kwargs["timestamp_list"] = _deserialize_timestamp_list( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["timestampList"] + ) + + case 5: + kwargs["enum_list"] = _deserialize_foo_enum_list( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["enumList"] + ) + + case 6: + kwargs["int_enum_list"] = _deserialize_integer_enum_list( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["intEnumList"] + ) + + case 7: + kwargs["nested_string_list"] = _deserialize_nested_string_list( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["nestedStringList"] + ) + + case 8: + kwargs["renamed_list_members"] = _deserialize_renamed_list_members( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["renamedListMembers"] + ) + + case 9: + kwargs["flattened_list"] = _deserialize_renamed_list_members( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["flattenedList"] + ) + + case 10: + kwargs["flattened_list2"] = _deserialize_renamed_list_members( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["flattenedList2"] + ) + + case 11: + kwargs["flattened_list_with_member_namespace"] = ( + _deserialize_list_with_member_namespace( + de, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members[ + "flattenedListWithMemberNamespace" + ], + ) + ) + + case 12: + kwargs["flattened_list_with_namespace"] = ( + _deserialize_list_with_namespace( + de, + _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members[ + "flattenedListWithNamespace" + ], + ) + ) + + case 13: + kwargs["structure_list"] = _deserialize_structure_list( + de, _SCHEMA_XML_EMPTY_LISTS_OUTPUT.members["structureList"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_EMPTY_LISTS_OUTPUT, consumer=_consumer) + return kwargs + + +XML_EMPTY_LISTS = APIOperation( + input=XmlEmptyListsInput, + output=XmlEmptyListsOutput, + schema=_SCHEMA_XML_EMPTY_LISTS, + input_schema=_SCHEMA_XML_EMPTY_LISTS_INPUT, + output_schema=_SCHEMA_XML_EMPTY_LISTS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlEmptyMapsInput: + """Dataclass for XmlEmptyMapsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_EMPTY_MAPS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_EMPTY_MAPS_INPUT, consumer=_consumer) + return kwargs + + +def _serialize_xml_maps_output_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, GreetingStruct] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_struct(value_schema, v)) + + +def _deserialize_xml_maps_output_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, GreetingStruct]: + result: dict[str, GreetingStruct] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = GreetingStruct.deserialize(d) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class XmlEmptyMapsOutput: + """Dataclass for XmlEmptyMapsOutput structure.""" + + my_map: dict[str, GreetingStruct] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_EMPTY_MAPS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.my_map is not None: + _serialize_xml_maps_output_map( + serializer, _SCHEMA_XML_EMPTY_MAPS_OUTPUT.members["myMap"], self.my_map + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["my_map"] = _deserialize_xml_maps_output_map( + de, _SCHEMA_XML_EMPTY_MAPS_OUTPUT.members["myMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_EMPTY_MAPS_OUTPUT, consumer=_consumer) + return kwargs + + +XML_EMPTY_MAPS = APIOperation( + input=XmlEmptyMapsInput, + output=XmlEmptyMapsOutput, + schema=_SCHEMA_XML_EMPTY_MAPS, + input_schema=_SCHEMA_XML_EMPTY_MAPS_INPUT, + output_schema=_SCHEMA_XML_EMPTY_MAPS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlEnumsInput: + """Dataclass for XmlEnumsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_ENUMS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_ENUMS_INPUT, consumer=_consumer) + return kwargs + + +def _serialize_foo_enum_set( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_foo_enum_set( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(FooEnum(d.read_string(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class XmlEnumsOutput: + """Dataclass for XmlEnumsOutput structure.""" + + foo_enum1: str | None = None + + foo_enum2: str | None = None + + foo_enum3: str | None = None + + foo_enum_list: list[str] | None = None + + foo_enum_set: list[str] | None = None + + foo_enum_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_ENUMS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo_enum1 is not None: + serializer.write_string( + _SCHEMA_XML_ENUMS_OUTPUT.members["fooEnum1"], self.foo_enum1 + ) + + if self.foo_enum2 is not None: + serializer.write_string( + _SCHEMA_XML_ENUMS_OUTPUT.members["fooEnum2"], self.foo_enum2 + ) + + if self.foo_enum3 is not None: + serializer.write_string( + _SCHEMA_XML_ENUMS_OUTPUT.members["fooEnum3"], self.foo_enum3 + ) + + if self.foo_enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_XML_ENUMS_OUTPUT.members["fooEnumList"], + self.foo_enum_list, + ) + + if self.foo_enum_set is not None: + _serialize_foo_enum_set( + serializer, + _SCHEMA_XML_ENUMS_OUTPUT.members["fooEnumSet"], + self.foo_enum_set, + ) + + if self.foo_enum_map is not None: + _serialize_foo_enum_map( + serializer, + _SCHEMA_XML_ENUMS_OUTPUT.members["fooEnumMap"], + self.foo_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo_enum1"] = FooEnum( + de.read_string(_SCHEMA_XML_ENUMS_OUTPUT.members["fooEnum1"]) + ) + + case 1: + kwargs["foo_enum2"] = FooEnum( + de.read_string(_SCHEMA_XML_ENUMS_OUTPUT.members["fooEnum2"]) + ) + + case 2: + kwargs["foo_enum3"] = FooEnum( + de.read_string(_SCHEMA_XML_ENUMS_OUTPUT.members["fooEnum3"]) + ) + + case 3: + kwargs["foo_enum_list"] = _deserialize_foo_enum_list( + de, _SCHEMA_XML_ENUMS_OUTPUT.members["fooEnumList"] + ) + + case 4: + kwargs["foo_enum_set"] = _deserialize_foo_enum_set( + de, _SCHEMA_XML_ENUMS_OUTPUT.members["fooEnumSet"] + ) + + case 5: + kwargs["foo_enum_map"] = _deserialize_foo_enum_map( + de, _SCHEMA_XML_ENUMS_OUTPUT.members["fooEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_ENUMS_OUTPUT, consumer=_consumer) + return kwargs + + +XML_ENUMS = APIOperation( + input=XmlEnumsInput, + output=XmlEnumsOutput, + schema=_SCHEMA_XML_ENUMS, + input_schema=_SCHEMA_XML_ENUMS_INPUT, + output_schema=_SCHEMA_XML_ENUMS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlIntEnumsInput: + """Dataclass for XmlIntEnumsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_INT_ENUMS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_INT_ENUMS_INPUT, consumer=_consumer) + return kwargs + + +def _serialize_integer_enum_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, int] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_integer(value_schema, v)) + + +def _deserialize_integer_enum_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, int]: + result: dict[str, int] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = IntegerEnum(d.read_integer(value_schema)) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_integer_enum_set( + serializer: ShapeSerializer, schema: Schema, value: list[int] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_integer(member_schema, e) + + +def _deserialize_integer_enum_set( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int]: + result: list[int] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(IntegerEnum(d.read_integer(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class XmlIntEnumsOutput: + """Dataclass for XmlIntEnumsOutput structure.""" + + int_enum1: int | None = None + + int_enum2: int | None = None + + int_enum3: int | None = None + + int_enum_list: list[int] | None = None + + int_enum_set: list[int] | None = None + + int_enum_map: dict[str, int] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_INT_ENUMS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.int_enum1 is not None: + serializer.write_integer( + _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnum1"], self.int_enum1 + ) + + if self.int_enum2 is not None: + serializer.write_integer( + _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnum2"], self.int_enum2 + ) + + if self.int_enum3 is not None: + serializer.write_integer( + _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnum3"], self.int_enum3 + ) + + if self.int_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnumList"], + self.int_enum_list, + ) + + if self.int_enum_set is not None: + _serialize_integer_enum_set( + serializer, + _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnumSet"], + self.int_enum_set, + ) + + if self.int_enum_map is not None: + _serialize_integer_enum_map( + serializer, + _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnumMap"], + self.int_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["int_enum1"] = IntegerEnum( + de.read_integer( + _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnum1"] + ) + ) + + case 1: + kwargs["int_enum2"] = IntegerEnum( + de.read_integer( + _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnum2"] + ) + ) + + case 2: + kwargs["int_enum3"] = IntegerEnum( + de.read_integer( + _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnum3"] + ) + ) + + case 3: + kwargs["int_enum_list"] = _deserialize_integer_enum_list( + de, _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnumList"] + ) + + case 4: + kwargs["int_enum_set"] = _deserialize_integer_enum_set( + de, _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnumSet"] + ) + + case 5: + kwargs["int_enum_map"] = _deserialize_integer_enum_map( + de, _SCHEMA_XML_INT_ENUMS_OUTPUT.members["intEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_INT_ENUMS_OUTPUT, consumer=_consumer) + return kwargs + + +XML_INT_ENUMS = APIOperation( + input=XmlIntEnumsInput, + output=XmlIntEnumsOutput, + schema=_SCHEMA_XML_INT_ENUMS, + input_schema=_SCHEMA_XML_INT_ENUMS_INPUT, + output_schema=_SCHEMA_XML_INT_ENUMS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlListsInput: + """Dataclass for XmlListsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_LISTS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_LISTS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class XmlListsOperationOutput: + """Dataclass for XmlListsOperationOutput structure.""" + + string_list: list[str] | None = None + + string_set: list[str] | None = None + + integer_list: list[int] | None = None + + boolean_list: list[bool] | None = None + + timestamp_list: list[datetime] | None = None + + enum_list: list[str] | None = None + + int_enum_list: list[int] | None = None + + nested_string_list: list[list[str]] | None = None + """A list of lists of strings.""" + + renamed_list_members: list[str] | None = None + + flattened_list: list[str] | None = None + + flattened_list2: list[str] | None = None + + flattened_list_with_member_namespace: list[str] | None = None + + flattened_list_with_namespace: list[str] | None = None + + structure_list: list[StructureListMember] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_LISTS_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string_list is not None: + _serialize_string_list( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["stringList"], + self.string_list, + ) + + if self.string_set is not None: + _serialize_string_set( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["stringSet"], + self.string_set, + ) + + if self.integer_list is not None: + _serialize_integer_list( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["integerList"], + self.integer_list, + ) + + if self.boolean_list is not None: + _serialize_boolean_list( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["booleanList"], + self.boolean_list, + ) + + if self.timestamp_list is not None: + _serialize_timestamp_list( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["timestampList"], + self.timestamp_list, + ) + + if self.enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["enumList"], + self.enum_list, + ) + + if self.int_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["intEnumList"], + self.int_enum_list, + ) + + if self.nested_string_list is not None: + _serialize_nested_string_list( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["nestedStringList"], + self.nested_string_list, + ) + + if self.renamed_list_members is not None: + _serialize_renamed_list_members( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["renamedListMembers"], + self.renamed_list_members, + ) + + if self.flattened_list is not None: + _serialize_renamed_list_members( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["flattenedList"], + self.flattened_list, + ) + + if self.flattened_list2 is not None: + _serialize_renamed_list_members( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["flattenedList2"], + self.flattened_list2, + ) + + if self.flattened_list_with_member_namespace is not None: + _serialize_list_with_member_namespace( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members[ + "flattenedListWithMemberNamespace" + ], + self.flattened_list_with_member_namespace, + ) + + if self.flattened_list_with_namespace is not None: + _serialize_list_with_namespace( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members[ + "flattenedListWithNamespace" + ], + self.flattened_list_with_namespace, + ) + + if self.structure_list is not None: + _serialize_structure_list( + serializer, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["structureList"], + self.structure_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string_list"] = _deserialize_string_list( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["stringList"] + ) + + case 1: + kwargs["string_set"] = _deserialize_string_set( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["stringSet"] + ) + + case 2: + kwargs["integer_list"] = _deserialize_integer_list( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["integerList"] + ) + + case 3: + kwargs["boolean_list"] = _deserialize_boolean_list( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["booleanList"] + ) + + case 4: + kwargs["timestamp_list"] = _deserialize_timestamp_list( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["timestampList"] + ) + + case 5: + kwargs["enum_list"] = _deserialize_foo_enum_list( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["enumList"] + ) + + case 6: + kwargs["int_enum_list"] = _deserialize_integer_enum_list( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["intEnumList"] + ) + + case 7: + kwargs["nested_string_list"] = _deserialize_nested_string_list( + de, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["nestedStringList"], + ) + + case 8: + kwargs["renamed_list_members"] = _deserialize_renamed_list_members( + de, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members[ + "renamedListMembers" + ], + ) + + case 9: + kwargs["flattened_list"] = _deserialize_renamed_list_members( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["flattenedList"] + ) + + case 10: + kwargs["flattened_list2"] = _deserialize_renamed_list_members( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["flattenedList2"] + ) + + case 11: + kwargs["flattened_list_with_member_namespace"] = ( + _deserialize_list_with_member_namespace( + de, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members[ + "flattenedListWithMemberNamespace" + ], + ) + ) + + case 12: + kwargs["flattened_list_with_namespace"] = ( + _deserialize_list_with_namespace( + de, + _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members[ + "flattenedListWithNamespace" + ], + ) + ) + + case 13: + kwargs["structure_list"] = _deserialize_structure_list( + de, _SCHEMA_XML_LISTS_OPERATION_OUTPUT.members["structureList"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_LISTS_OPERATION_OUTPUT, consumer=_consumer) + return kwargs + + +XML_LISTS = APIOperation( + input=XmlListsInput, + output=XmlListsOperationOutput, + schema=_SCHEMA_XML_LISTS, + input_schema=_SCHEMA_XML_LISTS_INPUT, + output_schema=_SCHEMA_XML_LISTS_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlMapsInput: + """Dataclass for XmlMapsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_MAPS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_MAPS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class XmlMapsOperationOutput: + """Dataclass for XmlMapsOperationOutput structure.""" + + my_map: dict[str, GreetingStruct] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_MAPS_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.my_map is not None: + _serialize_xml_maps_output_map( + serializer, + _SCHEMA_XML_MAPS_OPERATION_OUTPUT.members["myMap"], + self.my_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["my_map"] = _deserialize_xml_maps_output_map( + de, _SCHEMA_XML_MAPS_OPERATION_OUTPUT.members["myMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_MAPS_OPERATION_OUTPUT, consumer=_consumer) + return kwargs + + +XML_MAPS = APIOperation( + input=XmlMapsInput, + output=XmlMapsOperationOutput, + schema=_SCHEMA_XML_MAPS, + input_schema=_SCHEMA_XML_MAPS_INPUT, + output_schema=_SCHEMA_XML_MAPS_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlMapsXmlNameInput: + """Dataclass for XmlMapsXmlNameInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_MAPS_XML_NAME_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_MAPS_XML_NAME_INPUT, consumer=_consumer) + return kwargs + + +def _serialize_xml_maps_xml_name_output_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, GreetingStruct] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_struct(value_schema, v)) + + +def _deserialize_xml_maps_xml_name_output_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, GreetingStruct]: + result: dict[str, GreetingStruct] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = GreetingStruct.deserialize(d) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class XmlMapsXmlNameOutput: + """Dataclass for XmlMapsXmlNameOutput structure.""" + + my_map: dict[str, GreetingStruct] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_MAPS_XML_NAME_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.my_map is not None: + _serialize_xml_maps_xml_name_output_map( + serializer, + _SCHEMA_XML_MAPS_XML_NAME_OUTPUT.members["myMap"], + self.my_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["my_map"] = _deserialize_xml_maps_xml_name_output_map( + de, _SCHEMA_XML_MAPS_XML_NAME_OUTPUT.members["myMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_MAPS_XML_NAME_OUTPUT, consumer=_consumer) + return kwargs + + +XML_MAPS_XML_NAME = APIOperation( + input=XmlMapsXmlNameInput, + output=XmlMapsXmlNameOutput, + schema=_SCHEMA_XML_MAPS_XML_NAME, + input_schema=_SCHEMA_XML_MAPS_XML_NAME_INPUT, + output_schema=_SCHEMA_XML_MAPS_XML_NAME_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlNamespacesInput: + """Dataclass for XmlNamespacesInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_NAMESPACES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_NAMESPACES_INPUT, consumer=_consumer) + return kwargs + + +def _serialize_xml_namespaced_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_xml_namespaced_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class XmlNamespaceNested: + """Dataclass for XmlNamespaceNested structure.""" + + foo: str | None = None + + values: list[str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_NAMESPACE_NESTED, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_XML_NAMESPACE_NESTED.members["foo"], self.foo + ) + + if self.values is not None: + _serialize_xml_namespaced_list( + serializer, _SCHEMA_XML_NAMESPACE_NESTED.members["values"], self.values + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_XML_NAMESPACE_NESTED.members["foo"] + ) + + case 1: + kwargs["values"] = _deserialize_xml_namespaced_list( + de, _SCHEMA_XML_NAMESPACE_NESTED.members["values"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_NAMESPACE_NESTED, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class XmlNamespacesOutput: + """Dataclass for XmlNamespacesOutput structure.""" + + nested: XmlNamespaceNested | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_NAMESPACES_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.nested is not None: + serializer.write_struct( + _SCHEMA_XML_NAMESPACES_OUTPUT.members["nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["nested"] = XmlNamespaceNested.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_NAMESPACES_OUTPUT, consumer=_consumer) + return kwargs + + +XML_NAMESPACES = APIOperation( + input=XmlNamespacesInput, + output=XmlNamespacesOutput, + schema=_SCHEMA_XML_NAMESPACES, + input_schema=_SCHEMA_XML_NAMESPACES_INPUT, + output_schema=_SCHEMA_XML_NAMESPACES_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class XmlTimestampsInput: + """Dataclass for XmlTimestampsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_TIMESTAMPS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_TIMESTAMPS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class XmlTimestampsOutput: + """Dataclass for XmlTimestampsOutput structure.""" + + normal: datetime | None = None + + date_time: datetime | None = None + + date_time_on_target: datetime | None = None + + epoch_seconds: datetime | None = None + + epoch_seconds_on_target: datetime | None = None + + http_date: datetime | None = None + + http_date_on_target: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_XML_TIMESTAMPS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.normal is not None: + serializer.write_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["normal"], self.normal + ) + + if self.date_time is not None: + serializer.write_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["dateTime"], self.date_time + ) + + if self.date_time_on_target is not None: + serializer.write_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["dateTimeOnTarget"], + self.date_time_on_target, + ) + + if self.epoch_seconds is not None: + serializer.write_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["epochSeconds"], + self.epoch_seconds, + ) + + if self.epoch_seconds_on_target is not None: + serializer.write_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["epochSecondsOnTarget"], + self.epoch_seconds_on_target, + ) + + if self.http_date is not None: + serializer.write_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["httpDate"], self.http_date + ) + + if self.http_date_on_target is not None: + serializer.write_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["httpDateOnTarget"], + self.http_date_on_target, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["normal"] = de.read_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["normal"] + ) + + case 1: + kwargs["date_time"] = de.read_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["dateTime"] + ) + + case 2: + kwargs["date_time_on_target"] = de.read_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["dateTimeOnTarget"] + ) + + case 3: + kwargs["epoch_seconds"] = de.read_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["epochSeconds"] + ) + + case 4: + kwargs["epoch_seconds_on_target"] = de.read_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["epochSecondsOnTarget"] + ) + + case 5: + kwargs["http_date"] = de.read_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["httpDate"] + ) + + case 6: + kwargs["http_date_on_target"] = de.read_timestamp( + _SCHEMA_XML_TIMESTAMPS_OUTPUT.members["httpDateOnTarget"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_XML_TIMESTAMPS_OUTPUT, consumer=_consumer) + return kwargs + + +XML_TIMESTAMPS = APIOperation( + input=XmlTimestampsInput, + output=XmlTimestampsOutput, + schema=_SCHEMA_XML_TIMESTAMPS, + input_schema=_SCHEMA_XML_TIMESTAMPS_INPUT, + output_schema=_SCHEMA_XML_TIMESTAMPS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class StructArg: + """Dataclass for StructArg structure.""" + + string_arg: str | None = None + + other_arg: bool | None = None + + recursive_arg: "StructArg | None" = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STRUCT_ARG, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string_arg is not None: + serializer.write_string( + _SCHEMA_STRUCT_ARG.members["StringArg"], self.string_arg + ) + + if self.other_arg is not None: + serializer.write_boolean( + _SCHEMA_STRUCT_ARG.members["OtherArg"], self.other_arg + ) + + if self.recursive_arg is not None: + serializer.write_struct( + _SCHEMA_STRUCT_ARG.members["RecursiveArg"], self.recursive_arg + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string_arg"] = de.read_string( + _SCHEMA_STRUCT_ARG.members["StringArg"] + ) + + case 1: + kwargs["other_arg"] = de.read_boolean( + _SCHEMA_STRUCT_ARG.members["OtherArg"] + ) + + case 2: + kwargs["recursive_arg"] = StructArg.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_STRUCT_ARG, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class NestedStructuresInput: + """Dataclass for NestedStructuresInput structure.""" + + nested: "StructArg | None" = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NESTED_STRUCTURES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.nested is not None: + serializer.write_struct( + _SCHEMA_NESTED_STRUCTURES_INPUT.members["Nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["nested"] = StructArg.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NESTED_STRUCTURES_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class RecursiveXmlShapesOutputNested1: + """Dataclass for RecursiveXmlShapesOutputNested1 structure.""" + + foo: str | None = None + + nested: "RecursiveXmlShapesOutputNested2 | None" = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED1, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED1.members["foo"], self.foo + ) + + if self.nested is not None: + serializer.write_struct( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED1.members["nested"], + self.nested, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED1.members["foo"] + ) + + case 1: + kwargs["nested"] = RecursiveXmlShapesOutputNested2.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED1, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class RecursiveXmlShapesOutputNested2: + """Dataclass for RecursiveXmlShapesOutputNested2 structure.""" + + bar: str | None = None + + recursive_member: "RecursiveXmlShapesOutputNested1 | None" = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED2, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.bar is not None: + serializer.write_string( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED2.members["bar"], self.bar + ) + + if self.recursive_member is not None: + serializer.write_struct( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED2.members["recursiveMember"], + self.recursive_member, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["bar"] = de.read_string( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED2.members["bar"] + ) + + case 1: + kwargs["recursive_member"] = ( + RecursiveXmlShapesOutputNested1.deserialize(de) + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT_NESTED2, consumer=_consumer + ) + return kwargs + + +NESTED_STRUCTURES = APIOperation( + input=NestedStructuresInput, + output=NestedStructuresOutput, + schema=_SCHEMA_NESTED_STRUCTURES, + input_schema=_SCHEMA_NESTED_STRUCTURES_INPUT, + output_schema=_SCHEMA_NESTED_STRUCTURES_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class RecursiveXmlShapesOutput: + """Dataclass for RecursiveXmlShapesOutput structure.""" + + nested: "RecursiveXmlShapesOutputNested1 | None" = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.nested is not None: + serializer.write_struct( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT.members["nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["nested"] = RecursiveXmlShapesOutputNested1.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT, consumer=_consumer + ) + return kwargs + + +RECURSIVE_XML_SHAPES = APIOperation( + input=RecursiveXmlShapesInput, + output=RecursiveXmlShapesOutput, + schema=_SCHEMA_RECURSIVE_XML_SHAPES, + input_schema=_SCHEMA_RECURSIVE_XML_SHAPES_INPUT, + output_schema=_SCHEMA_RECURSIVE_XML_SHAPES_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) diff --git a/codegen-output/aws-query/src/awsquery/user_agent.py b/codegen-output/aws-query/src/awsquery/user_agent.py new file mode 100644 index 000000000..f998bd3c4 --- /dev/null +++ b/codegen-output/aws-query/src/awsquery/user_agent.py @@ -0,0 +1,17 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from smithy_aws_core.interceptors.user_agent import UserAgentInterceptor + +from . import __version__ +from .config import AsyncQueryProtocolConfig + + +def aws_user_agent_plugin(config: AsyncQueryProtocolConfig): + config.interceptors.append( + UserAgentInterceptor( + ua_suffix=config.user_agent_extra, + ua_app_id=config.sdk_ua_app_id, + sdk_version=__version__, + service_id="Query_Protocol", + ) + ) diff --git a/codegen-output/aws-query/tests/__init__.py b/codegen-output/aws-query/tests/__init__.py new file mode 100644 index 000000000..247be3e3d --- /dev/null +++ b/codegen-output/aws-query/tests/__init__.py @@ -0,0 +1 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. diff --git a/codegen-output/aws-query/tests/test_awsquery_protocol.py b/codegen-output/aws-query/tests/test_awsquery_protocol.py new file mode 100644 index 000000000..79ec2a1fc --- /dev/null +++ b/codegen-output/aws-query/tests/test_awsquery_protocol.py @@ -0,0 +1,4430 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from datetime import datetime, timezone +from urllib.parse import parse_qsl + +from pytest import fail, mark, raises +from smithy_aws_core.identity import StaticCredentialsResolver +from smithy_core.aio.retries import SimpleRetryStrategy +from smithy_core.aio.types import AsyncBytesReader +from smithy_core.aio.utils import async_list +from smithy_http import tuples_to_fields +from smithy_http.aio import HTTPResponse as _smithy_http_aio_HTTPResponse +from smithy_http.aio.interfaces import ( + HTTPRequest, + HTTPResponse as _smithy_http_aio_interfaces_HTTPResponse, +) +from smithy_http.interfaces import HTTPClientConfiguration, HTTPRequestConfiguration + +from awsquery.client import AsyncQueryProtocolClient +from awsquery.config import AsyncQueryProtocolConfig +from awsquery.models import ( + DatetimeOffsetsInput, + DatetimeOffsetsOutput, + EmptyInputAndEmptyOutputInput, + EmptyInputAndEmptyOutputOutput, + EndpointOperationInput, + EndpointWithHostLabelOperationInput, + FlattenedXmlMapInput, + FlattenedXmlMapOutput, + FlattenedXmlMapWithXmlNameInput, + FlattenedXmlMapWithXmlNameOutput, + FlattenedXmlMapWithXmlNamespaceInput, + FlattenedXmlMapWithXmlNamespaceOutput, + FractionalSecondsInput, + FractionalSecondsOutput, + GreetingStruct, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HostWithPathOperationInput, + IgnoresWrappingXmlNameInput, + IgnoresWrappingXmlNameOutput, + NestedStructWithList, + NestedStructWithMap, + NestedStructuresInput, + NoInputAndNoOutputInput, + NoInputAndNoOutputOutput, + NoInputAndOutputInput, + NoInputAndOutputOutput, + PutWithContentEncodingInput, + QueryIdempotencyTokenAutoFillInput, + QueryListsInput, + QueryMapsInput, + QueryTimestampsInput, + RecursiveXmlShapesInput, + RecursiveXmlShapesOutput, + RecursiveXmlShapesOutputNested1, + RecursiveXmlShapesOutputNested2, + ServiceError, + SimpleInputParamsInput, + SimpleScalarXmlPropertiesInput, + SimpleScalarXmlPropertiesOutput, + StructArg, + StructureListMember, + XmlBlobsInput, + XmlBlobsOperationOutput, + XmlEmptyBlobsInput, + XmlEmptyBlobsOutput, + XmlEmptyListsInput, + XmlEmptyListsOutput, + XmlEmptyMapsInput, + XmlEmptyMapsOutput, + XmlEnumsInput, + XmlEnumsOutput, + XmlIntEnumsInput, + XmlIntEnumsOutput, + XmlListsInput, + XmlListsOperationOutput, + XmlMapsInput, + XmlMapsOperationOutput, + XmlMapsXmlNameInput, + XmlMapsXmlNameOutput, + XmlNamespaceNested, + XmlNamespacesInput, + XmlNamespacesOutput, + XmlTimestampsInput, + XmlTimestampsOutput, +) + + +async def test_aws_query_date_time_with_negative_offset_response_datetime_offsets() -> ( + None +): + """ + Ensures that clients can correctly parse datetime (timestamps) with + offsets + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n 2019-12-16T22:48:18-01:00\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DatetimeOffsetsInput() + + try: + actual = await client.datetime_offsets(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DatetimeOffsetsOutput( + datetime_=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_aws_query_date_time_with_positive_offset_response_datetime_offsets() -> ( + None +): + """ + Ensures that clients can correctly parse datetime (timestamps) with + offsets + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n 2019-12-17T00:48:18+01:00\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DatetimeOffsetsInput() + + try: + actual = await client.datetime_offsets(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DatetimeOffsetsOutput( + datetime_=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_query_empty_input_and_empty_output_request_empty_input_and_empty_output() -> ( + None +): + """Empty input serializes no extra query params""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyInputAndEmptyOutputInput() + + try: + await client.empty_input_and_empty_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=EmptyInputAndEmptyOutput&Version=2020-01-08" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_empty_input_and_empty_output_response_empty_input_and_empty_output() -> ( + None +): + """Empty output""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient(status=200, headers=[], body=b""), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyInputAndEmptyOutputInput() + + try: + actual = await client.empty_input_and_empty_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = EmptyInputAndEmptyOutputOutput() + + assert actual == expected + + +@mark.xfail() +async def test_aws_query_endpoint_trait_request_endpoint_operation() -> None: + """ + Operations can prepend to the given host if they define the endpoint + trait. + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EndpointOperationInput() + + try: + await client.endpoint_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "foo.example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=EndpointOperation&Version=2020-01-08" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_aws_query_endpoint_trait_with_host_label_request_endpoint_with_host_label_operation() -> ( + None +): + """ + Operations can prepend to the given host if they define the endpoint + trait, and can use the host label trait to define further customization + based on user input. + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EndpointWithHostLabelOperationInput(label="bar") + + try: + await client.endpoint_with_host_label_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "foo.bar.example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b"Action=EndpointWithHostLabelOperation&Version=2020-01-08&label=bar" + ) + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_query_flattened_xml_map_response_flattened_xml_map() -> None: + """Serializes flattened XML maps in responses""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n foo\n Foo\n \n \n baz\n Baz\n \n \n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = FlattenedXmlMapInput() + + try: + actual = await client.flattened_xml_map(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = FlattenedXmlMapOutput(my_map={"foo": "Foo", "baz": "Baz"}) + + assert actual == expected + + +async def test_query_query_flattened_xml_map_with_xml_name_response_flattened_xml_map_with_xml_name() -> ( + None +): + """Serializes flattened XML maps in responses that have xmlName on members""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n a\n A\n \n \n b\n B\n \n \n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = FlattenedXmlMapWithXmlNameInput() + + try: + actual = await client.flattened_xml_map_with_xml_name(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = FlattenedXmlMapWithXmlNameOutput(my_map={"a": "A", "b": "B"}) + + assert actual == expected + + +async def test_query_query_flattened_xml_map_with_xml_namespace_response_flattened_xml_map_with_xml_namespace() -> ( + None +): + """ + Serializes flattened XML maps in responses that have xmlNamespace and + xmlName on members + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n a\n A\n \n \n b\n B\n \n \n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = FlattenedXmlMapWithXmlNamespaceInput() + + try: + actual = await client.flattened_xml_map_with_xml_namespace(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = FlattenedXmlMapWithXmlNamespaceOutput(my_map={"a": "A", "b": "B"}) + + assert actual == expected + + +async def test_aws_query_date_time_with_fractional_seconds_response_fractional_seconds() -> ( + None +): + """ + Ensures that clients can correctly parse datetime timestamps with + fractional seconds + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n 2000-01-02T20:34:56.123Z\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = FractionalSecondsInput() + + try: + actual = await client.fractional_seconds(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = FractionalSecondsOutput( + datetime_=datetime(2000, 1, 2, 20, 34, 56, 123000, timezone.utc) + ) + + assert actual == expected + + +async def test_query_greeting_with_errors_response_greeting_with_errors() -> None: + """ + Ensures that operations with errors successfully know how to deserialize + the successful response + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n Hello\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + actual = await client.greeting_with_errors(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = GreetingWithErrorsOutput(greeting="Hello") + + assert actual == expected + + +async def test_query_invalid_greeting_error_error_greeting_with_errors() -> None: + """Parses simple XML errors""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=400, + headers=[("Content-Type", "text/xml")], + body=b"\n \n Sender\n InvalidGreeting\n Hi\n \n foo-id\n\n", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'InvalidGreeting' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "InvalidGreeting": + fail( + f"Expected 'InvalidGreeting' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_complex_error_error_greeting_with_errors() -> None: + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=400, + headers=[("Content-Type", "text/xml")], + body=b"\n \n Sender\n ComplexError\n Top level\n \n bar\n \n \n foo-id\n\n", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'ComplexError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "ComplexError": + fail( + f"Expected 'ComplexError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_customized_error_error_greeting_with_errors() -> None: + """Parses customized XML errors""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=402, + headers=[("Content-Type", "text/xml")], + body=b"\n \n Sender\n Customized\n Hi\n \n foo-id\n\n", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'CustomCodeError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "CustomCodeError": + fail( + f"Expected 'CustomCodeError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_host_with_path_request_host_with_path_operation() -> None: + """Custom endpoints supplied by users can have paths""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/custom", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HostWithPathOperationInput() + + try: + await client.host_with_path_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/custom/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=HostWithPathOperation&Version=2020-01-08" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_ignores_wrapping_xml_name_response_ignores_wrapping_xml_name() -> ( + None +): + """The xmlName trait on the output structure is ignored in AWS Query""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n bar\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = IgnoresWrappingXmlNameInput() + + try: + actual = await client.ignores_wrapping_xml_name(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = IgnoresWrappingXmlNameOutput(foo="bar") + + assert actual == expected + + +async def test_nested_structures_request_nested_structures() -> None: + """Serializes nested structures using dots""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NestedStructuresInput( + nested=StructArg( + string_arg="foo", other_arg=True, recursive_arg=StructArg(string_arg="baz") + ) + ) + + try: + await client.nested_structures(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=NestedStructures&Version=2020-01-08&Nested.StringArg=foo&Nested.OtherArg=true&Nested.RecursiveArg.StringArg=baz" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_no_input_and_no_output_request_no_input_and_no_output() -> None: + """No input serializes no additional query params""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndNoOutputInput() + + try: + await client.no_input_and_no_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=NoInputAndNoOutput&Version=2020-01-08" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_no_input_and_no_output_response_no_input_and_no_output() -> None: + """Empty output. Note that no assertion is made on the output body itself.""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient(status=200, headers=[], body=b""), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndNoOutputInput() + + try: + actual = await client.no_input_and_no_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndNoOutputOutput() + + assert actual == expected + + +async def test_query_no_input_and_no_output_with_response_metadata_response_no_input_and_no_output() -> ( + None +): + """Empty output, but the server returns ResponseMetadata.""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[], + body=b"\n \n abc-123\n \n\n", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndNoOutputInput() + + try: + actual = await client.no_input_and_no_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndNoOutputOutput() + + assert actual == expected + + +async def test_query_no_input_and_output_request_no_input_and_output() -> None: + """No input serializes no payload""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndOutputInput() + + try: + await client.no_input_and_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=NoInputAndOutput&Version=2020-01-08" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_no_input_and_output_response_no_input_and_output() -> None: + """Empty output""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient(status=200, headers=[], body=b""), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndOutputInput() + + try: + actual = await client.no_input_and_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndOutputOutput() + + assert actual == expected + + +@mark.xfail() +async def test_sdk_applied_content_encoding_aws_query_request_put_with_content_encoding() -> ( + None +): + """ + Compression algorithm encoding is appended to the Content-Encoding + header. + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutWithContentEncodingInput( + data="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\n" + ) + + try: + await client.put_with_content_encoding(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-encoding", "gzip")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_sdk_appends_gzip_and_ignores_http_provided_encoding_aws_query_request_put_with_content_encoding() -> ( + None +): + """ + Compression algorithm encoding is appended to the Content-Encoding + header, and the user-provided content-encoding is NOT in the + Content-Encoding header since HTTP binding traits are ignored in the + awsQuery protocol. + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutWithContentEncodingInput( + encoding="custom", + data="RjCEL3kBwqPivZUXGiyA5JCujtWgJAkKRlnTEsNYfBRGOS0f7LT6R3bCSOXeJ4auSHzQ4BEZZTklUyj5\n1HEojihShQC2jkQJrNdGOZNSW49yRO0XbnGmeczUHbZqZRelLFKW4xjru9uTuB8lFCtwoGgciFsgqTF8\n5HYcoqINTRxuAwGuRUMoNO473QT0BtCQoKUkAyVaypG0hBZdGNoJhunBfW0d3HWTYlzz9pXElyZhq3C1\n2PDB17GEoOYXmTxDecysmPOdo5z6T0HFhujfeJFIQQ8dirmXcG4F3v0bZdf6AZ3jsiVh6RnEXIPxPbOi\ngIXDWTMUr4Pg3f2LdYCM01eAb2qTdgsEN0MUDhEIfn68I2tnWvcozyUFpg1ez6pyWP8ssWVfFrckREIM\nMb0cTUVqSVSM8bnFiF9SoXM6ZoGMKfX1mT708OYk7SqZ1JlCTkecDJDoR5ED2q2MWKUGR6jjnEV0GtD8\nWJO6AcF0DptY9Hk16Bav3z6c5FeBvrGDrxTFVgRUk8SychzjrcqJ4qskwN8rL3zslC0oqobQRnLFOvwJ\nprSzBIwdH2yAuxokXAdVRa1u9NGNRvfWJfKkwbbVz8yV76RUF9KNhAUmwyYDrLnxNj8ROl8B7dv8Gans\n7Bit52wcdiJyjBW1pAodB7zqqVwtBx5RaSpF7kEMXexYXp9N0J1jlXzdeg5Wgg4pO7TJNr2joiPVAiFf\nefwMMCNBkYx2z7cRxVxCJZMXXzxSKMGgdTN24bJ5UgE0TxyV52RC0wGWG49S1x5jGrvmxKCIgYPs0w3Z\n0I3XcdB0WEj4x4xRztB9Cx2Mc4qFYQdzS9kOioAgNBti1rBySZ8lFZM2zqxvBsJTTJsmcKPr1crqiXjM\noVWdM4ObOO6QA7Pu4c1hT68CrTmbcecjFcxHkgsqdixnFtN6keMGL9Z2YMjZOjYYzbUEwLJqUVWalkIB\nBkgBRqZpzxx5nB5t0qDH35KjsfKM5cinQaFoRq9y9Z82xdCoKZOsUbxZkk1kVmy1jPDCBhkhixkc5PKS\nFoSKTbeK7kuCEZCtR9OfF2k2MqbygGFsFu2sgb1Zn2YdDbaRwRGeaLhswta09UNSMUo8aTixgoYVHxwy\nvraLB6olPSPegeLOnmBeWyKmEfPdbpdGm4ev4vA2AUFuLIeFz0LkCSN0NgQMrr8ALEm1UNpJLReg1ZAX\nzZh7gtQTZUaBVdMJokaJpLk6FPxSA6zkwB5TegSqhrFIsmvpY3VNWmTUq7H0iADdh3dRQ8Is97bTsbwu\nvAEOjh4FQ9wPSFzEtcSJeYQft5GfWYPisDImjjvHVFshFFkNy2nN18pJmhVPoJc456tgbdfEIdGhIADC\n6UPcSSzE1FxlPpILqZrp3i4NvvKoiOa4a8tnALd2XRHHmsvALn2Wmfu07b86gZlu4yOyuUFNoWI6tFvd\nbHnqSJYNQlFESv13gJw609DBzNnrIgBGYBAcDRrIGAnflRKwVDUnDFrUQmE8xNG6jRlyb1p2Y2RrfBtG\ncKqhuGNiT2DfxpY89ektZ98waPhJrFEPJToNH8EADzBorh3T0h4YP1IeLmaI7SOxeuVrk1kjRqMK0rUB\nlUJgJNtCE35jCyoHMwPQlyi78ZaVv8COVQ24zcGpw0MTy6JUsDzAC3jLNY6xCb40SZV9XzG7nWvXA5Ej\nYC1gTXxF4AtFexIdDZ4RJbtYMyXt8LsEJerwwpkfqvDwsiFuqYC6vIn9RoZO5kI0F35XtUITDQYKZ4eq\nWBV0itxTyyR5Rp6g30pZEmEqOusDaIh96CEmHpOBYAQZ7u1QTfzRdysIGMpzbx5gj9Dxm2PO1glWzY7P\nlVqQiBlXSGDOkBkrB6SkiAxknt9zsPdTTsf3r3nid4hdiPrZmGWNgjOO1khSxZSzBdltrCESNnQmlnP5\nZOHA0eSYXwy8j4od5ZmjA3IpFOEPW2MutMbxIbJpg5dIx2x7WxespftenRLgl3CxcpPDcnb9w8LCHBg7\nSEjrEer6Y8wVLFWsQiv6nTdCPZz9cGqwgtCaiHRy8lTWFgdfWd397vw9rduGld3uUFeFRGjYrphqEmHi\nhiG0GhE6wRFVUsGJtvOCYkVREvbEdxPFeJvlAvOcs9HKbtptlTusvYB86vR2bNcIY4f5JZu2X6sGa354\n7LRk0ps2zqYjat3hMR7XDC8KiKceBteFsXoDjfVxTYKelpedTxqWAafrKhaoAVuNM98PSnkuIWGzjSUC\nNsDJTt6vt1D1afBVPWVmnQ7ZQdtEtLIEwAWYjemAztreELIr1E9fPEILm1Ke4KctP9I0I72Dh4eylNZD\n0DEr2Hg7cWFckuZ0Av5d0IPRARXikEGDHl8uh12TXL9v2Uh0ZVSJMEYvxGSbZvkWz8TjWSk3hKA2a7GL\nJm3Ho7e1C34gE1XRGcEthxvURxt4OKBqN3ZNaMIuDTWinoQAutMcUqtm4MoL7RGPiCHUrvTwQPSirsmA\nQmOEu8nOpnP77Fivh9jLGx5ta7nL6jrsWUsBqiN1lzpdPYLRR4mUIAj6sNWiDEk4pkbHSMEcqbWw6Zl7\npsEyPDHalCNhWMA3RSK3skURzQDZ0oBV5W7vjVIZ4d3uCKsk6zrzEI9u5mx7p9RdNKodXfzqYt0ULdtc\n3RW0hIfw2KvrO3BD2QrtgAkfrFBGVvlJSUoh0MvLz8DeXxfuiuq9Ttu7wvsqVI4Piah6WNEXtHHGPJO3\nGhc75Bnv2To4VS2v8rmyKAPIIVTuYBHZN6sZ4FhFzbrslCIdk0eadaU60naqiNWU3CsxplIYGyeThmJ7\n9u4h6Y2OmiPZjFPS2bAzwgAozYTVefII9aEaWZ0hxHZeu1FW7r79dkdO73ZqRfas9u8Z7LLBPCw5pV0F\n5I0pHDgNb6MogoxF4NZJfVtIX1vCHhhVLrXjrYNJU2fD9Fw8kT8Ie2HDBJnqAvYKmryQ1r9ulo3Me3rH\nq9s2Y5uCDxu9iQNhnpwIm57WYGFeqd2fnQeY2IziD3Jgx0KSrmOH0jgi0RwJyfGXaORPq3bQQqljuACo\nkO6io9t5VI8PbNxSHTRbtYiPciUslbT0g7SpCLrRPOBRJ4DDk56pjghpeoUagJ5xJ4wjBzBuXnAGkNnP\nTfpiuz2r3oSBAi8sB9wiYK2z9sp4gZyQsqdVNzAEgKatOxBRBmJCBYpjO98ZQrF83XApPpfFg0ujB2PW\n1iYF9NkgwIKB5oB6KVTOmSKJk11mVermPgeugHbzdd2zUP6fP8fWbhseqk2t8ahGvqjs2CDHFIWXl5jc\nfCknbykE3ANt7lnAfJQ2ddduLGiqrX4HWx6jcWw08Es6BkleO0IDbaWrb95d5isvFlzJsf0TyDIXF4uq\nbBDCi0XPWqtRJ2iqmnJa2GbBe9GmAOWMkBFSilMyC4sR395WSDpD56fx0NGoU6cHrRu9xF2Bgh7RGSfl\nch2GXEeE02fDpSHFNvJBlOEqqfkIX6oCa6KY9NThqeIjYsT184XR2ZI7akXRaw1gMOGpk4FmUxk6WIuX\n4ei1SLQgSdl7OEdRtJklZ76eFrMbkJQ2TDhu8f7mVuiy53GUMIvCrP9xYGZGmCIDm2e4U2BDi3F7C5xK\n3bDZXwlQp6z4BSqTy2OVEWxXUJfjPMOL5Mc7AvDeKtxAS73pVIv0HgHIa4NBAdC7uLG0zXuu1FF6z2XY\nyUhk03fMZhYe7vVxsul3WE7U01fuN8z2y0eKwBW1RFBE1eKIaR9Y01sIWQWbSrfHfDrdZiElhmhHehfs\n0EfrR4sLYdQshJuvhTeKGJDaEhtPQwwJ9mUYGtuCL9RozWx1XI4bHNlzBTW0BVokYiJGlPe7wdxNzJD7\nJgS7Lwv6jGKngVf86imGZyzqwiteWFPdNUoWdTvUPSMO5xIUK9mo5QpwbBOAmyYzVq42o3Qs90N9khEV\nU36LB99fw8PtGHH5wsCHshfauwnNPj0blGXzke0kQ4JNCVH7Jtn0Y0aeejkSxFtwtxoYs6zHl1Lxxpsd\nsw5vBy49CEtoltDW367lVAwDjWdx20msGB7qJCkEDrzu7EXSO22782QX9NBRcN9ppX0C25I0FMA4Wnhz\n9zIpiXRrsTH35jzM8Cjt4EVLGNU3O0HuEvAer3cENnMJtngdrT86ox3fihMQbiuy4Bh4DEcP5in2VjbT\n3qbnoCNvOi8Fmmf7KlGlWAOceL5OHVE5lljjQEMzEQOCEgrk5mDKgwSBJQBNauIDSC1a5iEQjB8Xxp4C\nqeKyyWY9IOntNrtU5ny4lNprHJd36dKFeBLKcGCOvgHBXdOZloMF0YTRExw7hreEO9IoTGVHJ4teWsNr\nHdtagUHjkeZkdMMfnUGNv5aBNtFMqhcZH6EitEa9lGPkKBbJpoom3u8D8EHSIF1H5EZqqx9TLY5hWAIG\nPwJ4qwkpCGw5rCLVrjw7ARKukIFzNULANqjHUMcJ002TlUosJM4xJ4aAgckpLVGOGuPDhGAAexEcQmbg\nUsZdmqQrtuVUyyLteLbLbqtR6CTlcAIwY3xyMCmPgyefE0FEUODBoxQtRUuYTL9RC5o1sYb2PvcxUQfb\niJFi2CAl99pAzcckU2qVCxniARslIxM5pmMRGsQX9ZzYAfZrbg6ce6S74I8UMlgRQ2QVyvUjKKOE6IrJ\nLng370emHfe5m6LZULD5YiZutkD5ipjL2Bz77DvTE5kNPUhuoKBcTJcUgytfXAKUTWOcRKNlq0GImrxM\nJfr7AWbLFFNKGLeTrVDBwpcokJCv0zcOKWe8fd2xkeXkZTdmM66IgM27cyYmtQ6YF26Kd0qrWJeVZJV9\n3fyLYYvKN5csbRY2BHoYE5ERARRW65IrpkXMf48OrCXMtDIP0Z7wxI9DiTeKKeH4uuguhCJnwzR3WxLA\nVU6eBJEd7ZjS6JA83w7decq8uDI7LGKjcz1FySp3B7fE9DkHRGXxbsL7Fjar6vW2mAv8CuvI20B6jctp\n2yLDs24sPfB3sSxrrlhbuT1m6DZqiN0dl6umKx7NGZhmOTVGr20jfcxhqPQwTJfd7kel4rvxip4BqkvT\n7STy8knJ2BXGyJeNgwo1PXUZRDVy0LCTsSF1RFuRZe8cktHl9lgw8ntdPn1pVFL0MwJkJfdXBNUp5gNv\n50FTkrpo1t6wq4CVbcfj2XOrOzvBUzNH26sXGABI1gGxCdp2jEZrHgqQaWIaTJVTuguZhxqDvdYsrwFW\nYN58uuNcKHIrGdRSigyZInwQDYk0pjcqdSeU0WVU3Y9htzZBR7XRaCJr5YTZvq7fwermb5tuwb37lPLq\nB2IGg0iftkVbXaSyfCwVaRbfLBb88so0QqpmJGirFu8FcDiXOV1zTr8yW9XLdYQuUjh43xrXLdgsuYff\nCagInUk1eU1aLjVZoJRsNmStmOEpAqlYMwTvx7w6j2f421Cxr5cNZBIVlAxlXN2QiDqJ9v3sHhHkTanc\nlQuH8ptUyX8qncpBuXXBn7cSez9N0EoxCBl1GHUagbjstgJo4gzLvTmVIY6MiWYOBitzNUHfyqKwtKUr\nVoSCdZcGeA9lHUPA7PUprRRaT3m1hGKPyshtVS2ikG48w3oVerln1N1qGdtz46gZCrndw3LZ1B362RfW\nzDPuXbpsyLsRMTt1Rz1oKHRXp3iE41hkhQH6pxlvyCW2INnHt5XU8zRamOB3oW0udOhMpQFDjRkOcy06\nb4t0QTHvoRqmBna3WXzIMZyeK3GChF5eF8oDXRbjhk7BB6YKCgqwWUzEJ5K47HMSlhFkBUjaPRjdGM0z\nzOMwhW6b1NvSwP7XM1P5yi1oPvOspts1vr29SXqrMMrBhVogeodWyd69NqrO4jkyBxKmlXifoTowpfiY\n2cUCE0XMZqxUN39LCP09JqZifaEcBEo3mgtm1tWu5QR2GNq7UyQf4RIPSDOpDCAtwoPhRgdT1lJdcj4U\nlnH0wrJ8Uwu7c08L7ErnIrDATqCrOjpSbzGP1xHENABYONC4TknFPrJ8pe40A8fzGT0qBw9mAM1SKcHO\nfoiLcMC9AjHTqJzDG3xplSLPG9or2rMeq7Fzp9r0y7uJRMxgg51EbjfvYlH466A3ggvL2WQlDXjJqPW3\nBJGWAWDNN9LK8f46bADKPxakpkx23S9O47rGSXfDhVSIZsDympxWX1UOzWwMZRHkofVeKqizgbKkGgUT\nWykE9gRoRAOd9wfHZDYKa9i0LaPDiaUMvnU1gdBIqIoiVsdJ9swX47oxvMtOxtcS0zlD6llDkBuIiU5g\nPwRCYmtkkb25c8iRJXwGFPjI1wJ34I1z1ENicPdosPiUe9ZC2jnXIKzEdv01x2ER7DNDF3yxOwOhxNxI\nGqsmC92j25UQQFu9ZstOZ28AoCkuOYs0Uycm5u8jR1T39dMBwrko09rC65ENLnsxM8oebmyFCPiGJ1ED\n5Xqc9qZ237f1OnETAoEOwqUSvrdPTv56U7hV91EMTyC812MLQpr2710E3VVpsUCUMNhIxdt7UXZ1UNFb\njgzpZLXnf4DHrv6B7kq6UI50KMxcw1HZE2GpODfUTzNFLaqdrvzxKe5eUWdcojBaRbD4fFdVYJTElYDH\nNNVh6ofkoeWcs9CWGFmSBe0T4K8phFeygQg0prKMELNEy6qENzVtG9ZDcqj3a7L6ZLtvq50anWp7fAVu\nfwz55g4iM2Z2fA0pnwHDL7tt67zTxGITvsnJsZSpeq1EQsZcwtkBV9liu7Rl7jiVT1IIRtchB8TsTiaA\nwVHIQQ9RIOTiPQdKNqi1kC9iGlUqWK93gblNWlBw1eYB9Wk8FQogutwTf0caNMx8D4nPbANcmOOlskIy\nzALh15OlTrWnhP95rf08AN2J026zDE2DUF9k0eCevYBQIDjqKNW4XCZnjbHoIcKzbY5VzPbMs3ZyMz8K\nSucBmgPg6wrSK5ykbkapS5vuqvXc9GbjQJ8bPNzoxoWGyjbZvDs2OBrIqBmcQb2DLJ8v38McQ4mC4UsS\njf4PyfSCtpk274QZjvLCZbLiCBxQegk7jUU0NmTFJAcYCxd9xMWdlFkiszcltT2YzwuFFz7iA6aa4n5L\nHpBNfUA01GcAi1aCMYhmooS4zSlYcSOZkovMz36U3Fd9WtqIEOJLi7HMgHQDgNMdK6DTzAdHQtxerxVF\nHJnPrfNVG7270r3bp0bPnLNYLhObbAn6zqSAUeLtI2Y4KJDjBKCAh2vvYGbu0e2REYJWRj7MkGevsSSy\nb1kCXLt6tKGWAb7lt5c0xyJgUIJW7pdtnwgT0ZCa24BecCAwNnG5U2EwQbcjZGsFxqNGfaemd3oFEhES\nBaE0Fxms9UKTnMafu8wvZ2xymMrUduuRzOjDeX7oD5YsLC88V8CGMLxbbxIpt94KGykbr6e7L0R4oZl1\ntKMgFwQ2p9Txdbp0Y293LcsJymKizqI0F2xEp7y4SmWOJqHZtsbz80wVV9nv41CvtfxuSoGZJ5cNB7pI\nBgzNcQCeH3Jt0RaGGwboxxpuFbzilmkMFXxJm87tD4WNgu01nHfGCKeQcySEBZpVfJgi6sDFJ8uWnvKm\n9mPLHurtWzEfKqUEa1iC71bXjw5wrvhv9BYW8JSUELHmDquftQyKdq0DZXhULMHGQLf4e95WIaoA14LL\nbThz77kuhKULPTu2MNrBUKGorurhGugo5gs4ZUezSsUOe3KxYdrFMdGgny1GgTxMSMTp2RAZytKjv4kQ\nVx7XgzvpQLIbDjUPAkJv6lScwIRq1W3Ne0Rh0V6Bmn6U5uIuWnJjULmbaQiSODj3z0mAZvak0mSWIGwT\nTX83HztcC4W7e1f6a1thmcc5K61Icehla2hBELWPpixTkyC4eEVmk9Rq0m0ZXtx0JX2ZQXqXDEyePyMe\nJ70sdSzXk72zusqhY4yuOMGgbYNHqxOToK6NxujR7e4dV3Wk5JnSUthym8scjcPeCiKDNY4cHfTMnDXJ\n9zLVy01LtNKYpJ1s8FxVxigmxQNKEbIamxhx6yqwGC4aiISVOOUEjvNOdaUfXfUsE6jEwtwxyGxjlRK1\ncLyxXttq4QWN6PehgHv7jXykzPjInbEysebFvvPOOMdunmJvcCNMSvjUda8fL6xfGo0FDrLg8XZipd6S\noPVdYtyIM1Dg40KbBA3JuumPYtXuJaHrZnjZmdnM5OVo4ZNxktfCVT0c6bnD4bAeyn4bYt1ZPaX6hQHh\nJtvNYfpD0ONYlmqKuToQAMlz52Fh6bj45EbX89L5eLlSpWeyBlGotzriB0EPlclrGi5l2B5oPb1aB1ag\nyyYuu44l0F1oOVYnBIZsxIsHVITxi9lEuVPFkWASOUNuVQXfM4n5hxWR9qtuKnIcPsvbJsv1U10XlKh3\nKisqPhHU15xrCLr5gwFxPUKiNTLUBrkzgBOHXPVsHcLCiSD0YU56TRGfvEom43TWUKPPfl9Z54tgVQuT\njCRlaljAzeniQIcbbHZnn3f0HxbDG3DFYqWSxNrXabHhRsIOhhUHSPENyhGSTVO5t0XX5CdMspJPCd02\n3Oqv32ccbUK4O3YH6LEvp0WO3kSl5n50odVkI9B0i0iq4UPFGMkM8bEQJbgJoOH71P10vtdevJFQE4g2\nyhimiM53ZJRWgSZveHtENZc0Gjo0F9eioak9BnPpY1QxAFPC817svuhEstcU69bLCA4D1rO5R8AuIIBq\nyQJcifFLvbpAEYTLKJqysZrU8EEl3TSdC13A9hZvk4NC8VGEDAxcNrKw313dZp17kZPO5HSd1y6sljAW\nA9M1d6FMYV5SlBWf3WZNCUPS7qKNlda2YBsC6IUVB363f5RLGQOQHwbaijBSRCkrVoRxBHtc0Bd5J9V9\nP5uMTXkpZOxRcCQvImGgcmGuxxLb5zTqfS2xu7v3Sf3IIesSt9tVzcEcdbEvLGVJkLk4mb3G30DbIbri\nPZ09JkweDvMaQ3bxT2nfkz3Ilihkw9jqikkCCCz7E8h6z6KbhQErEW9VzJZzMCgJsyPjFam6iNwpe07S\nhyOvNVw2t9wpzL5xM11DvVzQwDaWEytNRHzDBs4KwEtpI2IpjUyVZHSwA0UGqqkzoCgrJFlNOvPlXqcS\nIcREouUIBmuttkrhPWJtSxOOgpsdvBR3kTOzAXNzSKxoaBAb0c5SDMUc6FIyGA8x5wg5DkUgjFUUodEt\nOYaB2VHVePW9mxHeBTdKWLzJow4ZZvjnoBuVigXljKCNh137ckV2y3Yg3Xi4UzJEI2V5Rw9AfnMs7xUw\nVHOFCg189maD3bmZAe7b4eaGZhyy4HVKjqCXmIH7vsEjRvbnfB0SQxxpuqBDJbHNCtW4vM643ZQQBVPP\na7oXSQIq9w2dHp0A7dtkocCZdQp9FKR9XdJAFIbVSHzIF1ZogeZlc0pXuNE0tagvD57xwDRFkAuoQyMu\nYDdZasXrpSmEE5UjHVkyYsISn8QsfXurzDybX468aoRoks654jjmRY5zi1oB8TcMdC2c3sicNaqfeuhd\nH1nPX7l4RpdqWMR7gGx9slXtG8S3KxpOi4qCD7yg3saD66nun4dzksQURoTUdXyrJR5UpHsfIlTF1aJa\nMdXyQtQnrkl00TeghQd00rRFZsCnhi0qrCSKiBfB2EVrd9RPpbgwJGZHuIQecdBmNetc2ylSEClqVBPR\nGOPPIxrnswEZjmnS0jxKW9VSM1QVxSPJnPFswCqT95SoKD6CP4xdX28WIUGiNaIKodXXJHEIsXBCxLsr\nPwWPCtoplC6hhpKmW5dQo92iCTyY2KioKzO8XR6FKm6qonMKVEwQNtlYE9c97KMtEnp25VOdMP46SQXS\nYsSVp7vm8LP87VYI8SOKcW3s2oedYFtt45rvDzoTF0GmS6wELQ9uo98HhjQAI1Dt91cgjJOwygNmLoZE\nX5K2zQiNA163uMCl5xzaBqY4YTL0wgALg3IFdYSp0RFYLWdt6IxoGI1tnoxcjlUEPo5eGIc3mS3SmaLn\nOdumfUQQ4Jgmgaa5anUVQsfBDrlAN5oaX7O0JO71SSPSWiHBsT9WIPy2J1Cace9ZZLRxblFPSXcvsuHh\nhvnhWQltEDAe7MgvkFQ8lGVFa8jhzijoF9kLmMhMILSzYnfXnZPNP7TlAAwlLHK1RqlpHskJqb6CPpGP\nQvOAhEMsM3zJ2KejZx0esxkjxA0ZufVvGAMN3vTUMplQaF4RiQkp9fzBXf3CMk01dWjOMMIEXTeKzIQe\nEcffzjixWU9FpAyGp2rVl4ETRgqljOGw4UgK31r0ZIEGnH0xGz1FtbW1OcQM008JVujRqulCucEMmntr\n", + ) + + try: + await client.put_with_content_encoding(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-encoding", "gzip")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_query_protocol_idempotency_token_auto_fill_request_query_idempotency_token_auto_fill() -> ( + None +): + """Automatically adds idempotency token when not set""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryIdempotencyTokenAutoFillInput() + + try: + await client.query_idempotency_token_auto_fill(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryIdempotencyTokenAutoFill&Version=2020-01-08&token=00000000-0000-4000-8000-000000000000" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_protocol_idempotency_token_auto_fill_is_set_request_query_idempotency_token_auto_fill() -> ( + None +): + """Uses the given idempotency token as-is""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryIdempotencyTokenAutoFillInput( + token="00000000-0000-4000-8000-000000000123" + ) + + try: + await client.query_idempotency_token_auto_fill(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryIdempotencyTokenAutoFill&Version=2020-01-08&token=00000000-0000-4000-8000-000000000123" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_lists_request_query_lists() -> None: + """Serializes query lists""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryListsInput( + list_arg=["foo", "bar", "baz"], + complex_list_arg=[GreetingStruct(hi="hello"), GreetingStruct(hi="hola")], + ) + + try: + await client.query_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryLists&Version=2020-01-08&ListArg.member.1=foo&ListArg.member.2=bar&ListArg.member.3=baz&ComplexListArg.member.1.hi=hello&ComplexListArg.member.2.hi=hola" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_empty_query_lists_request_query_lists() -> None: + """Serializes empty query lists""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryListsInput(list_arg=[]) + + try: + await client.query_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryLists&Version=2020-01-08&ListArg=" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_flattened_query_lists_request_query_lists() -> None: + """ + Flattens query lists by repeating the member name and removing the + member element + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryListsInput(flattened_list_arg=["A", "B"]) + + try: + await client.query_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryLists&Version=2020-01-08&FlattenedListArg.1=A&FlattenedListArg.2=B" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_list_arg_with_xml_name_member_request_query_lists() -> None: + """Changes the member of lists using xmlName trait""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryListsInput(list_arg_with_xml_name_member=["A", "B"]) + + try: + await client.query_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryLists&Version=2020-01-08&ListArgWithXmlNameMember.item.1=A&ListArgWithXmlNameMember.item.2=B" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_flattened_list_arg_with_xml_name_request_query_lists() -> None: + """ + Changes the name of flattened lists using xmlName trait on the structure + member + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryListsInput(flattened_list_arg_with_xml_name=["A", "B"]) + + try: + await client.query_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryLists&Version=2020-01-08&Hi.1=A&Hi.2=B" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_nested_struct_with_list_request_query_lists() -> None: + """Nested structure with a list member""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryListsInput(nested_with_list=NestedStructWithList(list_arg=["A", "B"])) + + try: + await client.query_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryLists&Version=2020-01-08&NestedWithList.ListArg.member.1=A&NestedWithList.ListArg.member.2=B" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_simple_query_maps_request_query_maps() -> None: + """Serializes query maps""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryMapsInput(map_arg={"bar": "Bar", "foo": "Foo"}) + + try: + await client.query_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryMaps&Version=2020-01-08&MapArg.entry.1.key=bar&MapArg.entry.1.value=Bar&MapArg.entry.2.key=foo&MapArg.entry.2.value=Foo" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_simple_query_maps_with_xml_name_request_query_maps() -> None: + """Serializes query maps and uses xmlName""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryMapsInput(renamed_map_arg={"foo": "Foo"}) + + try: + await client.query_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryMaps&Version=2020-01-08&Foo.entry.1.key=foo&Foo.entry.1.value=Foo" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_complex_query_maps_request_query_maps() -> None: + """Serializes complex query maps""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryMapsInput( + complex_map_arg={ + "bar": GreetingStruct(hi="Bar"), + "foo": GreetingStruct(hi="Foo"), + } + ) + + try: + await client.query_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryMaps&Version=2020-01-08&ComplexMapArg.entry.1.key=bar&ComplexMapArg.entry.1.value.hi=Bar&ComplexMapArg.entry.2.key=foo&ComplexMapArg.entry.2.value.hi=Foo" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_empty_query_maps_request_query_maps() -> None: + """Does not serialize empty query maps""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryMapsInput(map_arg={}) + + try: + await client.query_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryMaps&Version=2020-01-08" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_query_map_with_member_xml_name_request_query_maps() -> None: + """Serializes query maps where the member has an xmlName trait""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryMapsInput(map_with_xml_member_name={"bar": "Bar", "foo": "Foo"}) + + try: + await client.query_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryMaps&Version=2020-01-08&MapWithXmlMemberName.entry.1.K=bar&MapWithXmlMemberName.entry.1.V=Bar&MapWithXmlMemberName.entry.2.K=foo&MapWithXmlMemberName.entry.2.V=Foo" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_flattened_query_maps_request_query_maps() -> None: + """Serializes flattened query maps""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryMapsInput(flattened_map={"bar": "Bar", "foo": "Foo"}) + + try: + await client.query_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryMaps&Version=2020-01-08&FlattenedMap.1.key=bar&FlattenedMap.1.value=Bar&FlattenedMap.2.key=foo&FlattenedMap.2.value=Foo" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_flattened_query_maps_with_xml_name_request_query_maps() -> None: + """Serializes flattened query maps that use an xmlName""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryMapsInput(flattened_map_with_xml_name={"bar": "Bar", "foo": "Foo"}) + + try: + await client.query_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryMaps&Version=2020-01-08&Hi.1.K=bar&Hi.1.V=Bar&Hi.2.K=foo&Hi.2.V=Foo" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_query_map_of_lists_request_query_maps() -> None: + """Serializes query map of lists""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryMapsInput(map_of_lists={"bar": ["C", "D"], "foo": ["A", "B"]}) + + try: + await client.query_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryMaps&Version=2020-01-08&MapOfLists.entry.1.key=bar&MapOfLists.entry.1.value.member.1=C&MapOfLists.entry.1.value.member.2=D&MapOfLists.entry.2.key=foo&MapOfLists.entry.2.value.member.1=A&MapOfLists.entry.2.value.member.2=B" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_nested_struct_with_map_request_query_maps() -> None: + """Serializes nested struct with map member""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryMapsInput( + nested_struct_with_map=NestedStructWithMap(map_arg={"bar": "Bar", "foo": "Foo"}) + ) + + try: + await client.query_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryMaps&Version=2020-01-08&NestedStructWithMap.MapArg.entry.1.key=bar&NestedStructWithMap.MapArg.entry.1.value=Bar&NestedStructWithMap.MapArg.entry.2.key=foo&NestedStructWithMap.MapArg.entry.2.value=Foo" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_timestamps_input_request_query_timestamps() -> None: + """Serializes timestamps""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryTimestampsInput( + normal_format=datetime(2015, 1, 25, 8, 0, 0, 0, timezone.utc), + epoch_member=datetime(2015, 1, 25, 8, 0, 0, 0, timezone.utc), + epoch_target=datetime(2015, 1, 25, 8, 0, 0, 0, timezone.utc), + ) + + try: + await client.query_timestamps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=QueryTimestamps&Version=2020-01-08&normalFormat=2015-01-25T08%3A00%3A00Z&epochMember=1422172800&epochTarget=1422172800" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_recursive_shapes_response_recursive_xml_shapes() -> None: + """Serializes recursive structures""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n Foo1\n \n Bar1\n \n Foo2\n \n Bar2\n \n \n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = RecursiveXmlShapesInput() + + try: + actual = await client.recursive_xml_shapes(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = RecursiveXmlShapesOutput( + nested=RecursiveXmlShapesOutputNested1( + foo="Foo1", + nested=RecursiveXmlShapesOutputNested2( + bar="Bar1", + recursive_member=RecursiveXmlShapesOutputNested1( + foo="Foo2", nested=RecursiveXmlShapesOutputNested2(bar="Bar2") + ), + ), + ) + ) + + assert actual == expected + + +async def test_query_simple_input_params_strings_request_simple_input_params() -> None: + """Serializes strings""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(foo="val1", bar="val2") + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b"Action=SimpleInputParams&Version=2020-01-08&Foo=val1&Bar=val2" + ) + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_simple_input_params_string_and_boolean_true_request_simple_input_params() -> ( + None +): + """Serializes booleans that are true""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(foo="val1", baz=True) + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b"Action=SimpleInputParams&Version=2020-01-08&Foo=val1&Baz=true" + ) + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_simple_input_params_strings_and_boolean_false_request_simple_input_params() -> ( + None +): + """Serializes booleans that are false""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(baz=False) + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=SimpleInputParams&Version=2020-01-08&Baz=false" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_simple_input_params_integer_request_simple_input_params() -> None: + """Serializes integers""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(bam=10) + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=SimpleInputParams&Version=2020-01-08&Bam=10" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_simple_input_params_float_request_simple_input_params() -> None: + """Serializes floats""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(boo=float(10.8)) + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=SimpleInputParams&Version=2020-01-08&Boo=10.8" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_simple_input_params_blob_request_simple_input_params() -> None: + """Blobs are base64 encoded in the query string""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(qux=b"value") + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b"Action=SimpleInputParams&Version=2020-01-08&Qux=dmFsdWU%3D" + ) + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_enums_request_simple_input_params() -> None: + """Serializes enums in the query string""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(foo_enum="Foo") + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b"Action=SimpleInputParams&Version=2020-01-08&FooEnum=Foo" + ) + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_int_enums_request_simple_input_params() -> None: + """Serializes intEnums in the query string""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(integer_enum=1) + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b"Action=SimpleInputParams&Version=2020-01-08&IntegerEnum=1" + ) + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_query_supports_na_n_float_inputs_request_simple_input_params() -> ( + None +): + """Supports handling NaN float values.""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(float_value=float("nan"), boo=float("nan")) + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b"Action=SimpleInputParams&Version=2020-01-08&FloatValue=NaN&Boo=NaN" + ) + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_query_supports_infinity_float_inputs_request_simple_input_params() -> ( + None +): + """Supports handling Infinity float values.""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(float_value=float("inf"), boo=float("inf")) + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=SimpleInputParams&Version=2020-01-08&FloatValue=Infinity&Boo=Infinity" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_aws_query_supports_negative_infinity_float_inputs_request_simple_input_params() -> ( + None +): + """Supports handling -Infinity float values.""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleInputParamsInput(float_value=float("-inf"), boo=float("-inf")) + + try: + await client.simple_input_params(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/x-www-form-urlencoded") + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"Action=SimpleInputParams&Version=2020-01-08&FloatValue=-Infinity&Boo=-Infinity" + actual_params = sorted( + parse_qsl(actual_body_content.decode(), keep_blank_values=True) + ) + expected_params = sorted( + parse_qsl(expected_body_content.decode(), keep_blank_values=True) + ) + assert actual_params == expected_params + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_query_simple_scalar_properties_response_simple_scalar_xml_properties() -> ( + None +): + """Serializes simple scalar properties""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n string\n \n true\n false\n 1\n 2\n 3\n 4\n 5.5\n 6.5\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarXmlPropertiesInput() + + try: + actual = await client.simple_scalar_xml_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarXmlPropertiesOutput( + string_value="string", + empty_string_value="", + true_boolean_value=True, + false_boolean_value=False, + byte_value=1, + short_value=2, + integer_value=3, + long_value=4, + float_value=float(5.5), + double_value=float(6.5), + ) + + assert actual == expected + + +@mark.xfail() +async def test_aws_query_supports_na_n_float_outputs_response_simple_scalar_xml_properties() -> ( + None +): + """Supports handling NaN float values.""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n NaN\n NaN\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarXmlPropertiesInput() + + try: + actual = await client.simple_scalar_xml_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarXmlPropertiesOutput( + float_value=float("nan"), double_value=float("nan") + ) + + assert actual == expected + + +async def test_aws_query_supports_infinity_float_outputs_response_simple_scalar_xml_properties() -> ( + None +): + """Supports handling Infinity float values.""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n Infinity\n Infinity\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarXmlPropertiesInput() + + try: + actual = await client.simple_scalar_xml_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarXmlPropertiesOutput( + float_value=float("inf"), double_value=float("inf") + ) + + assert actual == expected + + +async def test_aws_query_supports_negative_infinity_float_outputs_response_simple_scalar_xml_properties() -> ( + None +): + """Supports handling -Infinity float values.""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n -Infinity\n -Infinity\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarXmlPropertiesInput() + + try: + actual = await client.simple_scalar_xml_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarXmlPropertiesOutput( + float_value=float("-inf"), double_value=float("-inf") + ) + + assert actual == expected + + +async def test_query_xml_blobs_response_xml_blobs() -> None: + """Blobs are base64 encoded""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n dmFsdWU=\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlBlobsInput() + + try: + actual = await client.xml_blobs(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlBlobsOperationOutput(data=b"value") + + assert actual == expected + + +async def test_query_xml_empty_blobs_response_xml_empty_blobs() -> None: + """Empty blobs are deserialized as empty string""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlEmptyBlobsInput() + + try: + actual = await client.xml_empty_blobs(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlEmptyBlobsOutput(data=b"") + + assert actual == expected + + +async def test_query_xml_empty_self_closed_blobs_response_xml_empty_blobs() -> None: + """Empty self closed blobs are deserialized as empty string""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlEmptyBlobsInput() + + try: + actual = await client.xml_empty_blobs(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlEmptyBlobsOutput(data=b"") + + assert actual == expected + + +async def test_query_xml_empty_lists_response_xml_empty_lists() -> None: + """Deserializes empty XML lists""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlEmptyListsInput() + + try: + actual = await client.xml_empty_lists(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlEmptyListsOutput(string_list=[], string_set=[]) + + assert actual == expected + + +async def test_query_xml_empty_maps_response_xml_empty_maps() -> None: + """Deserializes Empty XML maps""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlEmptyMapsInput() + + try: + actual = await client.xml_empty_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlEmptyMapsOutput(my_map={}) + + assert actual == expected + + +async def test_query_xml_empty_self_closed_maps_response_xml_empty_maps() -> None: + """Deserializes Self-Closed XML maps""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlEmptyMapsInput() + + try: + actual = await client.xml_empty_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlEmptyMapsOutput(my_map={}) + + assert actual == expected + + +async def test_query_xml_enums_response_xml_enums() -> None: + """Serializes simple scalar properties""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n Foo\n 0\n 1\n \n Foo\n 0\n \n \n Foo\n 0\n \n \n \n hi\n Foo\n \n \n zero\n 0\n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlEnumsInput() + + try: + actual = await client.xml_enums(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlEnumsOutput( + foo_enum1="Foo", + foo_enum2="0", + foo_enum3="1", + foo_enum_list=["Foo", "0"], + foo_enum_set=["Foo", "0"], + foo_enum_map={"hi": "Foo", "zero": "0"}, + ) + + assert actual == expected + + +async def test_query_xml_int_enums_response_xml_int_enums() -> None: + """Serializes simple scalar properties""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n 1\n 2\n 3\n \n 1\n 2\n \n \n 1\n 2\n \n \n \n a\n 1\n \n \n b\n 2\n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlIntEnumsInput() + + try: + actual = await client.xml_int_enums(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlIntEnumsOutput( + int_enum1=1, + int_enum2=2, + int_enum3=3, + int_enum_list=[1, 2], + int_enum_set=[1, 2], + int_enum_map={"a": 1, "b": 2}, + ) + + assert actual == expected + + +async def test_query_xml_lists_response_xml_lists() -> None: + """Tests for XML list serialization""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n foo\n bar\n \n \n foo\n bar\n \n \n 1\n 2\n \n \n true\n false\n \n \n 2014-04-29T18:30:38Z\n 2014-04-29T18:30:38Z\n \n \n Foo\n 0\n \n \n 1\n 2\n \n \n \n foo\n bar\n \n \n baz\n qux\n \n \n \n foo\n bar\n \n hi\n bye\n yep\n nope\n a\n b\n a\n b\n \n \n 1\n 2\n \n \n 3\n 4\n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlListsInput() + + try: + actual = await client.xml_lists(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlListsOperationOutput( + string_list=["foo", "bar"], + string_set=["foo", "bar"], + integer_list=[1, 2], + boolean_list=[True, False], + timestamp_list=[ + datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc), + datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc), + ], + enum_list=["Foo", "0"], + int_enum_list=[1, 2], + nested_string_list=[["foo", "bar"], ["baz", "qux"]], + renamed_list_members=["foo", "bar"], + flattened_list=["hi", "bye"], + flattened_list2=["yep", "nope"], + flattened_list_with_member_namespace=["a", "b"], + flattened_list_with_namespace=["a", "b"], + structure_list=[ + StructureListMember(a="1", b="2"), + StructureListMember(a="3", b="4"), + ], + ) + + assert actual == expected + + +async def test_query_xml_maps_response_xml_maps() -> None: + """Tests for XML map serialization""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlMapsInput() + + try: + actual = await client.xml_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlMapsOperationOutput( + my_map={"foo": GreetingStruct(hi="there"), "baz": GreetingStruct(hi="bye")} + ) + + assert actual == expected + + +async def test_query_query_xml_maps_xml_name_response_xml_maps_xml_name() -> None: + """Serializes XML lists""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n \n foo\n \n there\n \n \n \n baz\n \n bye\n \n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlMapsXmlNameInput() + + try: + actual = await client.xml_maps_xml_name(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlMapsXmlNameOutput( + my_map={"foo": GreetingStruct(hi="there"), "baz": GreetingStruct(hi="bye")} + ) + + assert actual == expected + + +async def test_query_xml_namespaces_response_xml_namespaces() -> None: + """Serializes XML namespaces""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n \n Foo\n \n Bar\n Baz\n \n \n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlNamespacesInput() + + try: + actual = await client.xml_namespaces(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlNamespacesOutput( + nested=XmlNamespaceNested(foo="Foo", values=["Bar", "Baz"]) + ) + + assert actual == expected + + +async def test_query_xml_timestamps_response_xml_timestamps() -> None: + """Tests how normal timestamps are serialized""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n 2014-04-29T18:30:38Z\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlTimestampsInput() + + try: + actual = await client.xml_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlTimestampsOutput( + normal=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_query_xml_timestamps_with_date_time_format_response_xml_timestamps() -> ( + None +): + """ + Ensures that the timestampFormat of date-time works like normal + timestamps + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n 2014-04-29T18:30:38Z\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlTimestampsInput() + + try: + actual = await client.xml_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlTimestampsOutput( + date_time=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_query_xml_timestamps_with_date_time_on_target_format_response_xml_timestamps() -> ( + None +): + """ + Ensures that the timestampFormat of date-time on the target shape works + like normal timestamps + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n 2014-04-29T18:30:38Z\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlTimestampsInput() + + try: + actual = await client.xml_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlTimestampsOutput( + date_time_on_target=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_query_xml_timestamps_with_epoch_seconds_format_response_xml_timestamps() -> ( + None +): + """Ensures that the timestampFormat of epoch-seconds works""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n 1398796238\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlTimestampsInput() + + try: + actual = await client.xml_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlTimestampsOutput( + epoch_seconds=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_query_xml_timestamps_with_epoch_seconds_on_target_format_response_xml_timestamps() -> ( + None +): + """ + Ensures that the timestampFormat of epoch-seconds on the target shape + works + """ + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n 1398796238\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlTimestampsInput() + + try: + actual = await client.xml_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlTimestampsOutput( + epoch_seconds_on_target=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_query_xml_timestamps_with_http_date_format_response_xml_timestamps() -> ( + None +): + """Ensures that the timestampFormat of http-date works""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n Tue, 29 Apr 2014 18:30:38 GMT\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlTimestampsInput() + + try: + actual = await client.xml_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlTimestampsOutput( + http_date=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_query_xml_timestamps_with_http_date_on_target_format_response_xml_timestamps() -> ( + None +): + """Ensures that the timestampFormat of http-date on the target shape works""" + client = AsyncQueryProtocolClient( + config=await AsyncQueryProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/xml")], + body=b'\n \n Tue, 29 Apr 2014 18:30:38 GMT\n \n\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = XmlTimestampsInput() + + try: + actual = await client.xml_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = XmlTimestampsOutput( + http_date_on_target=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +class TestHttpServiceError(ServiceError): + """A test error that subclasses the service-error for protocol tests.""" + + def __init__(self, request: HTTPRequest): + self.request = request + + +class RequestTestHTTPClient: + """An asynchronous HTTP client solely for testing purposes.""" + + TIMEOUT_EXCEPTIONS = () + SUPPORTS_DUPLEX_STREAMING: bool = True + + def __init__(self, *, client_config: HTTPClientConfiguration | None = None): + self._client_config = client_config + + async def send( + self, + request: HTTPRequest, + *, + request_config: HTTPRequestConfiguration | None = None, + ) -> _smithy_http_aio_interfaces_HTTPResponse: + # Raise the exception with the request object to bypass actual request handling + raise TestHttpServiceError(request) + + +class ResponseTestHTTPClient: + """An asynchronous HTTP client solely for testing purposes.""" + + TIMEOUT_EXCEPTIONS = () + SUPPORTS_DUPLEX_STREAMING: bool = True + + def __init__( + self, + *, + client_config: HTTPClientConfiguration | None = None, + status: int = 200, + headers: list[tuple[str, str]] | None = None, + body: bytes = b"", + ): + self._client_config = client_config + self.status = status + self.fields = tuples_to_fields(headers or []) + self.body = body + + async def send( + self, + request: HTTPRequest, + *, + request_config: HTTPRequestConfiguration | None = None, + ) -> _smithy_http_aio_HTTPResponse: + # Pre-construct the response from the request and return it + return _smithy_http_aio_HTTPResponse( + status=self.status, fields=self.fields, body=async_list([self.body]) + ) diff --git a/codegen-output/rest-json-1/README.md b/codegen-output/rest-json-1/README.md new file mode 100644 index 000000000..1af099403 --- /dev/null +++ b/codegen-output/rest-json-1/README.md @@ -0,0 +1,5 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +## Sample Rest Json Protocol Service Client + +restjson client diff --git a/codegen-output/rest-json-1/pyproject.toml b/codegen-output/rest-json-1/pyproject.toml new file mode 100644 index 000000000..d3bb00ab7 --- /dev/null +++ b/codegen-output/rest-json-1/pyproject.toml @@ -0,0 +1,66 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +[project] +name = "restjson" +version = "0.0.1" +description = "restjson client" +readme = "README.md" +requires-python = ">=3.12" +keywords = ["smithy", "restjson"] +license = {text = "Apache-2.0"} +classifiers = [ + "Development Status :: 2 - Pre-Alpha", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Natural Language :: English", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14" +] + +dependencies = [ + "smithy_aws_core[eventstream, json]~=0.11.0", + "smithy_core~=0.8.0", + "smithy_http[aiohttp]~=0.5.0" +] + +[project.optional-dependencies] +awscrt = [ + "smithy_http[awscrt]~=0.5.0" +] + +[dependency-groups] +test = [ + "pytest>=9.0.1,<10.0.0", + "pytest-asyncio>=1.3.0,<1.4.0" +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.pyright] +typeCheckingMode = "strict" +reportPrivateUsage = false +reportUnusedFunction = false +reportUnusedVariable = false +reportUnnecessaryComparison = false +reportUnusedClass = false +enableExperimentalFeatures = true + +[tool.ruff] +target-version = "py312" + +[tool.ruff.lint] +ignore = ["F841"] + +[tool.ruff.format] +skip-magic-trailing-comma = true + +[tool.pytest.ini_options] +python_classes = ["!Test"] +asyncio_mode = "auto" diff --git a/codegen-output/rest-json-1/src/restjson/__init__.py b/codegen-output/rest-json-1/src/restjson/__init__.py new file mode 100644 index 000000000..30f6d44e9 --- /dev/null +++ b/codegen-output/rest-json-1/src/restjson/__init__.py @@ -0,0 +1,3 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +__version__: str = "0.0.1" diff --git a/codegen-output/rest-json-1/src/restjson/_private/__init__.py b/codegen-output/rest-json-1/src/restjson/_private/__init__.py new file mode 100644 index 000000000..247be3e3d --- /dev/null +++ b/codegen-output/rest-json-1/src/restjson/_private/__init__.py @@ -0,0 +1 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. diff --git a/codegen-output/rest-json-1/src/restjson/_private/schemas.py b/codegen-output/rest-json-1/src/restjson/_private/schemas.py new file mode 100644 index 000000000..6a584d0ab --- /dev/null +++ b/codegen-output/rest-json-1/src/restjson/_private/schemas.py @@ -0,0 +1,19306 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from types import MappingProxyType + +from smithy_core.prelude import ( + BLOB, + BOOLEAN, + BYTE, + DOUBLE, + FLOAT, + INTEGER, + LONG, + SHORT, + STRING, + TIMESTAMP, + UNIT, +) +from smithy_core.schemas import Schema +from smithy_core.shapes import ShapeID, ShapeType +from smithy_core.traits import Trait + + +BOOLEAN_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#BooleanList"), + shape_type=ShapeType.LIST, + members={"member": {"target": BOOLEAN}}, +) + +DOUBLE_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#DoubleList"), + shape_type=ShapeType.LIST, + members={"member": {"target": DOUBLE}}, +) + +FOO_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnum"), + shape_type=ShapeType.ENUM, + members={ + "FOO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Foo")], + }, + "BAZ": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Baz")], + }, + "BAR": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="Bar")], + }, + "ONE": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="1")], + }, + "ZERO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="0")], + }, + }, +) + +FOO_ENUM_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnumList"), + shape_type=ShapeType.LIST, + members={"member": {"target": FOO_ENUM}}, +) + +INTEGER_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnum"), + shape_type=ShapeType.INT_ENUM, + traits=[Trait.new(id=ShapeID("smithy.api#box"))], + members={ + "A": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=1)], + }, + "B": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=2)], + }, + "C": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=3)], + }, + }, +) + +INTEGER_ENUM_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnumList"), + shape_type=ShapeType.LIST, + members={"member": {"target": INTEGER_ENUM}}, +) + +INTEGER_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerList"), + shape_type=ShapeType.LIST, + members={"member": {"target": INTEGER}}, +) + +INTEGER_SET = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerSet"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#uniqueItems"))], + members={"member": {"target": INTEGER}}, +) + +STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING}}, +) + +STRING_LIST_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringListMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING_LIST}}, +) + +STRING_SET = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringSet"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#uniqueItems"))], + members={"member": {"target": STRING}}, +) + +TIMESTAMP_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#TimestampList"), + shape_type=ShapeType.LIST, + members={"member": {"target": TIMESTAMP}}, +) + +ALL_QUERY_STRING_TYPES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#AllQueryStringTypesInput"), + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("HttpQueryParamsTrait",)), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "queryString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="String")], + }, + "queryStringList": { + "target": STRING_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="StringList") + ], + }, + "queryStringSet": { + "target": STRING_SET, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="StringSet") + ], + }, + "queryByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Byte")], + }, + "queryShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Short")], + }, + "queryInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Integer")], + }, + "queryIntegerList": { + "target": INTEGER_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="IntegerList") + ], + }, + "queryIntegerSet": { + "target": INTEGER_SET, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="IntegerSet") + ], + }, + "queryLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Long")], + }, + "queryFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Float")], + }, + "queryDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Double")], + }, + "queryDoubleList": { + "target": DOUBLE_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="DoubleList") + ], + }, + "queryBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Boolean")], + }, + "queryBooleanList": { + "target": BOOLEAN_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="BooleanList") + ], + }, + "queryTimestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Timestamp") + ], + }, + "queryTimestampList": { + "target": TIMESTAMP_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="TimestampList") + ], + }, + "queryEnum": { + "target": FOO_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Enum")], + }, + "queryEnumList": { + "target": FOO_ENUM_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="EnumList")], + }, + "queryIntegerEnum": { + "target": INTEGER_ENUM, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="IntegerEnum") + ], + }, + "queryIntegerEnumList": { + "target": INTEGER_ENUM_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="IntegerEnumList") + ], + }, + "queryParamsMapOfStringList": { + "target": STRING_LIST_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQueryParams"))], + }, + }, +) + +ALL_QUERY_STRING_TYPES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#AllQueryStringTypesOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +ALL_QUERY_STRING_TYPES = Schema( + id=ShapeID("aws.protocoltests.restjson#AllQueryStringTypes"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonAllQueryStringTypes", + "documentation": "Serializes query string parameters with all supported types", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/AllQueryStringTypesInput", + "body": "", + "queryParams": ( + "String=Hello%20there", + "StringList=a", + "StringList=b", + "StringList=c", + "StringSet=a", + "StringSet=b", + "StringSet=c", + "Byte=1", + "Short=2", + "Integer=3", + "IntegerList=1", + "IntegerList=2", + "IntegerList=3", + "IntegerSet=1", + "IntegerSet=2", + "IntegerSet=3", + "Long=4", + "Float=1.1", + "Double=1.1", + "DoubleList=1.1", + "DoubleList=2.1", + "DoubleList=3.1", + "Boolean=true", + "BooleanList=true", + "BooleanList=false", + "BooleanList=true", + "Timestamp=1970-01-01T00%3A00%3A01Z", + "TimestampList=1970-01-01T00%3A00%3A01Z", + "TimestampList=1970-01-01T00%3A00%3A02Z", + "TimestampList=1970-01-01T00%3A00%3A03Z", + "Enum=Foo", + "EnumList=Foo", + "EnumList=Baz", + "EnumList=Bar", + "IntegerEnum=1", + "IntegerEnumList=1", + "IntegerEnumList=2", + "IntegerEnumList=3", + ), + "params": MappingProxyType( + { + "queryString": "Hello there", + "queryStringList": ("a", "b", "c"), + "queryStringSet": ("a", "b", "c"), + "queryByte": 1, + "queryShort": 2, + "queryInteger": 3, + "queryIntegerList": (1, 2, 3), + "queryIntegerSet": (1, 2, 3), + "queryLong": 4, + "queryFloat": 1.1, + "queryDouble": 1.1, + "queryDoubleList": (1.1, 2.1, 3.1), + "queryBoolean": True, + "queryBooleanList": (True, False, True), + "queryTimestamp": 1, + "queryTimestampList": (1, 2, 3), + "queryEnum": "Foo", + "queryEnumList": ("Foo", "Baz", "Bar"), + "queryIntegerEnum": 1, + "queryIntegerEnumList": (1, 2, 3), + "queryParamsMapOfStringList": MappingProxyType( + { + "String": ("Hello there",), + "StringList": ("a", "b", "c"), + "StringSet": ("a", "b", "c"), + "Byte": ("1",), + "Short": ("2",), + "Integer": ("3",), + "IntegerList": ("1", "2", "3"), + "IntegerSet": ("1", "2", "3"), + "Long": ("4",), + "Float": ("1.1",), + "Double": ("1.1",), + "DoubleList": ("1.1", "2.1", "3.1"), + "Boolean": ("true",), + "BooleanList": ("true", "false", "true"), + "Timestamp": ("1970-01-01T00:00:01Z",), + "TimestampList": ( + "1970-01-01T00:00:01Z", + "1970-01-01T00:00:02Z", + "1970-01-01T00:00:03Z", + ), + "Enum": ("Foo",), + "EnumList": ("Foo", "Baz", "Bar"), + "IntegerEnum": ("1",), + "IntegerEnumList": ("1", "2", "3"), + } + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryStringMap", + "documentation": "Handles query string maps", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/AllQueryStringTypesInput", + "body": "", + "queryParams": ( + "QueryParamsStringKeyA=Foo", + "QueryParamsStringKeyB=Bar", + ), + "params": MappingProxyType( + { + "queryParamsMapOfStringList": MappingProxyType( + { + "QueryParamsStringKeyA": ("Foo",), + "QueryParamsStringKeyB": ("Bar",), + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryStringEscaping", + "documentation": "Handles escaping all required characters in the query string.", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/AllQueryStringTypesInput", + "body": "", + "queryParams": ( + "String=%20%25%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D%F0%9F%98%B9", + ), + "params": MappingProxyType( + { + "queryString": " %:/?#[]@!$&'()*+,;=😹", + "queryParamsMapOfStringList": MappingProxyType( + {"String": (" %:/?#[]@!$&'()*+,;=😹",)} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNaNFloatQueryValues", + "documentation": "Supports handling NaN float query values.", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/AllQueryStringTypesInput", + "body": "", + "queryParams": ("Float=NaN", "Double=NaN"), + "params": MappingProxyType( + { + "queryFloat": "NaN", + "queryDouble": "NaN", + "queryParamsMapOfStringList": MappingProxyType( + {"Float": ("NaN",), "Double": ("NaN",)} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsInfinityFloatQueryValues", + "documentation": "Supports handling Infinity float query values.", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/AllQueryStringTypesInput", + "body": "", + "queryParams": ("Float=Infinity", "Double=Infinity"), + "params": MappingProxyType( + { + "queryFloat": "Infinity", + "queryDouble": "Infinity", + "queryParamsMapOfStringList": MappingProxyType( + {"Float": ("Infinity",), "Double": ("Infinity",)} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNegativeInfinityFloatQueryValues", + "documentation": "Supports handling -Infinity float query values.", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/AllQueryStringTypesInput", + "body": "", + "queryParams": ("Float=-Infinity", "Double=-Infinity"), + "params": MappingProxyType( + { + "queryFloat": "-Infinity", + "queryDouble": "-Infinity", + "queryParamsMapOfStringList": MappingProxyType( + {"Float": ("-Infinity",), "Double": ("-Infinity",)} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonZeroAndFalseQueryValues", + "documentation": "Query values of 0 and false are serialized", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/AllQueryStringTypesInput", + "body": "", + "queryParams": ("Integer=0", "Boolean=false"), + "params": MappingProxyType( + { + "queryInteger": 0, + "queryBoolean": False, + "queryParamsMapOfStringList": MappingProxyType( + {"Integer": ("0",), "Boolean": ("false",)} + ), + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/AllQueryStringTypesInput", "method": "GET"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +BLOB_PAYLOAD_EVENT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#BlobPayloadEvent"), + members={ + "payload": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#eventPayload"))], + } + }, +) + +CLIENT_OPTIONAL_DEFAULTS = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ClientOptionalDefaults"), + members={ + "member": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=0), + Trait.new(id=ShapeID("smithy.api#clientOptional")), + ], + } + }, +) + +COMPLEX_NESTED_ERROR_DATA = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ComplexNestedErrorData"), + members={ + "Foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#jsonName"), value="Fooooo")], + } + }, +) + +COMPLEX_ERROR = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ComplexError"), + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonComplexErrorWithNoMessage", + "documentation": "Serializes a complex error with no message member", + "protocol": "aws.protocols#restJson1", + "params": MappingProxyType( + { + "Header": "Header", + "TopLevel": "Top level", + "Nested": MappingProxyType({"Foo": "bar"}), + } + ), + "code": 403, + "headers": MappingProxyType( + { + "Content-Type": "application/json", + "X-Header": "Header", + "X-Amzn-Errortype": "ComplexError", + } + ), + "body": '{\n "TopLevel": "Top level",\n "Nested": {\n "Fooooo": "bar"\n }\n}', + "bodyMediaType": "application/json", + } + ), + MappingProxyType( + { + "id": "RestJsonEmptyComplexErrorWithNoMessage", + "protocol": "aws.protocols#restJson1", + "params": MappingProxyType({}), + "code": 403, + "headers": MappingProxyType( + { + "Content-Type": "application/json", + "X-Amzn-Errortype": "ComplexError", + } + ), + "body": "{}", + "bodyMediaType": "application/json", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="client"), + Trait.new(id=ShapeID("smithy.api#httpError"), value=403), + ], + members={ + "Header": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Header") + ], + }, + "TopLevel": {"target": STRING}, + "Nested": {"target": COMPLEX_NESTED_ERROR_DATA}, + }, +) + +CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ConstantAndVariableQueryStringInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "baz": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="baz")], + }, + "maybeSet": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="maybeSet")], + }, + }, +) + +CONSTANT_AND_VARIABLE_QUERY_STRING_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ConstantAndVariableQueryStringOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +CONSTANT_AND_VARIABLE_QUERY_STRING = Schema( + id=ShapeID("aws.protocoltests.restjson#ConstantAndVariableQueryString"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonConstantAndVariableQueryStringMissingOneValue", + "documentation": "Mixes constant and variable query string parameters", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/ConstantAndVariableQueryString", + "queryParams": ("foo=bar", "baz=bam"), + "forbidQueryParams": ("maybeSet",), + "body": "", + "params": MappingProxyType({"baz": "bam"}), + } + ), + MappingProxyType( + { + "id": "RestJsonConstantAndVariableQueryStringAllValues", + "documentation": "Mixes constant and variable query string parameters", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/ConstantAndVariableQueryString", + "queryParams": ("foo=bar", "baz=bam", "maybeSet=yes"), + "body": "", + "params": MappingProxyType({"baz": "bam", "maybeSet": "yes"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/ConstantAndVariableQueryString?foo=bar", "method": "GET"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +CONSTANT_QUERY_STRING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ConstantQueryStringInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "hello": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + } + }, +) + +CONSTANT_QUERY_STRING_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ConstantQueryStringOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +CONSTANT_QUERY_STRING = Schema( + id=ShapeID("aws.protocoltests.restjson#ConstantQueryString"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonConstantQueryString", + "documentation": "Includes constant query string parameters", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/ConstantQueryString/hi", + "queryParams": ("foo=bar", "hello"), + "body": "", + "params": MappingProxyType({"hello": "hi"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/ConstantQueryString/{hello}?foo=bar&hello", "method": "GET"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +CONTENT_TYPE_PARAMETERS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ContentTypeParametersInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"value": {"target": INTEGER}}, +) + +CONTENT_TYPE_PARAMETERS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ContentTypeParametersOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], +) + +CONTENT_TYPE_PARAMETERS = Schema( + id=ShapeID("aws.protocoltests.restjson#ContentTypeParameters"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonMustSupportParametersInContentType", + "documentation": "A server should ignore parameters added to the content type", + "uri": "/ContentTypeParameters", + "method": "POST", + "protocol": "aws.protocols#restJson1", + "body": '{"value":5}', + "headers": MappingProxyType( + {"Content-Type": "application/json; charset=utf-8"} + ), + "params": MappingProxyType({"value": 5}), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/ContentTypeParameters", "method": "POST"}), + ), + ], +) + +DATETIME_OFFSETS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DatetimeOffsetsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +DATE_TIME = Schema( + id=ShapeID("aws.protocoltests.shared#DateTime"), + shape_type=ShapeType.TIMESTAMP, + traits=[Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time")], +) + +DATETIME_OFFSETS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DatetimeOffsetsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"datetime": {"target": DATE_TIME}}, +) + +DATETIME_OFFSETS = Schema( + id=ShapeID("aws.protocoltests.restjson#DatetimeOffsets"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonDateTimeWithNegativeOffset", + "documentation": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": ' {\n "datetime": "2019-12-16T22:48:18-01:00"\n }\n', + "params": MappingProxyType({"datetime": 1576540098}), + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonDateTimeWithPositiveOffset", + "documentation": "Ensures that clients can correctly parse datetime (timestamps) with offsets", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": ' {\n "datetime": "2019-12-17T00:48:18+01:00"\n }\n', + "params": MappingProxyType({"datetime": 1576540098}), + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/DatetimeOffsets", "method": "POST"}), + ), + ], +) + +DOCUMENT = Schema( + id=ShapeID("aws.protocoltests.restjson#Document"), shape_type=ShapeType.DOCUMENT +) + +TEST_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestEnum"), + shape_type=ShapeType.ENUM, + members={ + "FOO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="FOO")], + }, + "BAR": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="BAR")], + }, + "BAZ": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value="BAZ")], + }, + }, +) + +TEST_INT_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestIntEnum"), + shape_type=ShapeType.INT_ENUM, + traits=[Trait.new(id=ShapeID("smithy.api#box"))], + members={ + "ONE": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=1)], + }, + "TWO": { + "target": UNIT, + "traits": [Trait.new(id=ShapeID("smithy.api#enumValue"), value=2)], + }, + }, +) + +TEST_STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestStringList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING}}, +) + +TEST_STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestStringMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +DEFAULTS = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#Defaults"), + members={ + "defaultString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "defaultBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=True)], + }, + "defaultList": { + "target": TEST_STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "defaultDocumentMap": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + "defaultDocumentString": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "defaultDocumentBoolean": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=True)], + }, + "defaultDocumentList": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "defaultNullDocument": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=None)], + }, + "defaultTimestamp": { + "target": TIMESTAMP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "defaultBlob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="YWJj")], + }, + "defaultByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "defaultShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "defaultInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=10)], + }, + "defaultLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=100)], + }, + "defaultFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1.0)], + }, + "defaultDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1.0)], + }, + "defaultMap": { + "target": TEST_STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + "defaultEnum": { + "target": TEST_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="FOO")], + }, + "defaultIntEnum": { + "target": TEST_INT_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "emptyString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="")], + }, + "falseBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=False)], + }, + "emptyBlob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="")], + }, + "zeroByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0.0)], + }, + "zeroDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0.0)], + }, + }, +) + +DENSE_BOOLEAN_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DenseBooleanMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": BOOLEAN}}, +) + +DENSE_NUMBER_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DenseNumberMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": INTEGER}}, +) + +DENSE_SET_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DenseSetMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING_SET}}, +) + +DENSE_STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DenseStringMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +GREETING_STRUCT = Schema.collection( + id=ShapeID("aws.protocoltests.shared#GreetingStruct"), + members={"hi": {"target": STRING}}, +) + +DENSE_STRUCT_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DenseStructMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": GREETING_STRUCT}}, +) + +FAREWELL = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#Farewell"), + members={ + "phrase": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="bye")], + } + }, +) + +DIALOG = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#Dialog"), + members={ + "language": {"target": STRING}, + "greeting": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "farewell": {"target": FAREWELL}, + }, +) + +DIALOG_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DialogList"), + shape_type=ShapeType.LIST, + members={"member": {"target": DIALOG}}, +) + +DIALOG_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DialogMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": DIALOG}}, +) + +DOCUMENT_TYPE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DocumentTypeInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#DocumentTypeInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"stringValue": {"target": STRING}, "documentValue": {"target": DOCUMENT}}, +) + +DOCUMENT_TYPE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DocumentTypeOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#DocumentTypeInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"stringValue": {"target": STRING}, "documentValue": {"target": DOCUMENT}}, +) + +DOCUMENT_TYPE = Schema( + id=ShapeID("aws.protocoltests.restjson#DocumentType"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "DocumentTypeInputWithObject", + "documentation": "Serializes document types as part of the JSON request payload with no escaping.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/DocumentType", + "body": '{\n "stringValue": "string",\n "documentValue": {\n "foo": "bar"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "stringValue": "string", + "documentValue": MappingProxyType({"foo": "bar"}), + } + ), + } + ), + MappingProxyType( + { + "id": "DocumentInputWithString", + "documentation": "Serializes document types using a string.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/DocumentType", + "body": '{\n "stringValue": "string",\n "documentValue": "hello"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"stringValue": "string", "documentValue": "hello"} + ), + } + ), + MappingProxyType( + { + "id": "DocumentInputWithNumber", + "documentation": "Serializes document types using a number.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/DocumentType", + "body": '{\n "stringValue": "string",\n "documentValue": 10\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"stringValue": "string", "documentValue": 10} + ), + } + ), + MappingProxyType( + { + "id": "DocumentInputWithBoolean", + "documentation": "Serializes document types using a boolean.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/DocumentType", + "body": '{\n "stringValue": "string",\n "documentValue": true\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"stringValue": "string", "documentValue": True} + ), + } + ), + MappingProxyType( + { + "id": "DocumentInputWithList", + "documentation": "Serializes document types using a list.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/DocumentType", + "body": '{\n "stringValue": "string",\n "documentValue": [\n true,\n "hi",\n [\n 1,\n 2\n ],\n {\n "foo": {\n "baz": [\n 3,\n 4\n ]\n }\n }\n ]\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "stringValue": "string", + "documentValue": ( + True, + "hi", + (1, 2), + MappingProxyType( + {"foo": MappingProxyType({"baz": (3, 4)})} + ), + ), + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "DocumentOutput", + "documentation": "Serializes documents as part of the JSON response payload with no escaping.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "stringValue": "string",\n "documentValue": {\n "foo": "bar"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "stringValue": "string", + "documentValue": MappingProxyType({"foo": "bar"}), + } + ), + } + ), + MappingProxyType( + { + "id": "DocumentOutputString", + "documentation": "Document types can be JSON scalars too.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "stringValue": "string",\n "documentValue": "hello"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"stringValue": "string", "documentValue": "hello"} + ), + } + ), + MappingProxyType( + { + "id": "DocumentOutputNumber", + "documentation": "Document types can be JSON scalars too.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "stringValue": "string",\n "documentValue": 10\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"stringValue": "string", "documentValue": 10} + ), + } + ), + MappingProxyType( + { + "id": "DocumentOutputBoolean", + "documentation": "Document types can be JSON scalars too.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "stringValue": "string",\n "documentValue": false\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"stringValue": "string", "documentValue": False} + ), + } + ), + MappingProxyType( + { + "id": "DocumentOutputArray", + "documentation": "Document types can be JSON arrays.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "stringValue": "string",\n "documentValue": [\n true,\n false\n ]\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"stringValue": "string", "documentValue": (True, False)} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/DocumentType", "method": "PUT"}), + ), + ], +) + +DOCUMENT_VALUED_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DocumentValuedMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": DOCUMENT}}, +) + +DOCUMENT_TYPE_AS_MAP_VALUE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DocumentTypeAsMapValueInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#DocumentTypeAsMapValueInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"docValuedMap": {"target": DOCUMENT_VALUED_MAP}}, +) + +DOCUMENT_TYPE_AS_MAP_VALUE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DocumentTypeAsMapValueOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#DocumentTypeAsMapValueInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"docValuedMap": {"target": DOCUMENT_VALUED_MAP}}, +) + +DOCUMENT_TYPE_AS_MAP_VALUE = Schema( + id=ShapeID("aws.protocoltests.restjson#DocumentTypeAsMapValue"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "DocumentTypeAsMapValueInput", + "documentation": "Serializes a map that uses documents as the value.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/DocumentTypeAsMapValue", + "body": '{\n "docValuedMap": {\n "foo": { "f": 1, "o": 2 },\n "bar": [ "b", "a", "r" ],\n "baz": "BAZ"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "docValuedMap": MappingProxyType( + { + "foo": MappingProxyType({"f": 1, "o": 2}), + "bar": ("b", "a", "r"), + "baz": "BAZ", + } + ) + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "DocumentTypeAsMapValueOutput", + "documentation": "Serializes a map that uses documents as the value.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "docValuedMap": {\n "foo": { "f": 1, "o": 2 },\n "bar": [ "b", "a", "r" ],\n "baz": "BAZ"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "docValuedMap": MappingProxyType( + { + "foo": MappingProxyType({"f": 1, "o": 2}), + "bar": ("b", "a", "r"), + "baz": "BAZ", + } + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/DocumentTypeAsMapValue", "method": "PUT"}), + ), + ], +) + +DOCUMENT_TYPE_AS_PAYLOAD_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DocumentTypeAsPayloadInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#DocumentTypeAsPayloadInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "documentValue": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +DOCUMENT_TYPE_AS_PAYLOAD_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DocumentTypeAsPayloadOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#DocumentTypeAsPayloadInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "documentValue": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +DOCUMENT_TYPE_AS_PAYLOAD = Schema( + id=ShapeID("aws.protocoltests.restjson#DocumentTypeAsPayload"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "DocumentTypeAsPayloadInput", + "documentation": "Serializes a document as the target of the httpPayload trait.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/DocumentTypeAsPayload", + "body": '{\n "foo": "bar"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"documentValue": MappingProxyType({"foo": "bar"})} + ), + } + ), + MappingProxyType( + { + "id": "DocumentTypeAsPayloadInputString", + "documentation": "Serializes a document as the target of the httpPayload trait using a string.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/DocumentTypeAsPayload", + "body": '"hello"', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"documentValue": "hello"}), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "DocumentTypeAsPayloadOutput", + "documentation": "Serializes a document as the target of the httpPayload trait.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "foo": "bar"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"documentValue": MappingProxyType({"foo": "bar"})} + ), + } + ), + MappingProxyType( + { + "id": "DocumentTypeAsPayloadOutputString", + "documentation": "Serializes a document as a payload string.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '"hello"', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"documentValue": "hello"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/DocumentTypeAsPayload", "method": "PUT"}), + ), + ], +) + +ERROR_EVENT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ErrorEvent"), + traits=[Trait.new(id=ShapeID("smithy.api#error"), value="client")], + members={"message": {"target": STRING}}, +) + +HEADERS_EVENT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HeadersEvent"), + members={ + "booleanHeader": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + "byteHeader": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + "shortHeader": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + "intHeader": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + "longHeader": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + "blobHeader": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + "stringHeader": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + "timestampHeader": { + "target": DATE_TIME, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + }, +) + +PAYLOAD_STRUCTURE = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PayloadStructure"), + members={"structureMember": {"target": STRING}}, +) + +HEADERS_AND_EXPLICIT_PAYLOAD_EVENT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HeadersAndExplicitPayloadEvent"), + members={ + "header": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + "payload": { + "target": PAYLOAD_STRUCTURE, + "traits": [Trait.new(id=ShapeID("smithy.api#eventPayload"))], + }, + }, +) + +HEADERS_AND_IMPLICIT_PAYLOAD_EVENT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HeadersAndImplicitPayloadEvent"), + members={ + "header": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#eventHeader"))], + }, + "payload": {"target": STRING}, + }, +) + +STRING_PAYLOAD_EVENT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StringPayloadEvent"), + members={ + "payload": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#eventPayload"))], + } + }, +) + +STRUCTURE_PAYLOAD_EVENT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StructurePayloadEvent"), + members={ + "payload": { + "target": PAYLOAD_STRUCTURE, + "traits": [Trait.new(id=ShapeID("smithy.api#eventPayload"))], + } + }, +) + +PAYLOAD_UNION = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PayloadUnion"), + shape_type=ShapeType.UNION, + members={"unionMember": {"target": STRING}}, +) + +UNION_PAYLOAD_EVENT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#UnionPayloadEvent"), + members={ + "payload": { + "target": PAYLOAD_UNION, + "traits": [Trait.new(id=ShapeID("smithy.api#eventPayload"))], + } + }, +) + +EVENT_STREAM = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#EventStream"), + shape_type=ShapeType.UNION, + traits=[Trait.new(id=ShapeID("smithy.api#streaming"))], + members={ + "headers": {"target": HEADERS_EVENT}, + "blobPayload": {"target": BLOB_PAYLOAD_EVENT}, + "stringPayload": {"target": STRING_PAYLOAD_EVENT}, + "structurePayload": {"target": STRUCTURE_PAYLOAD_EVENT}, + "unionPayload": {"target": UNION_PAYLOAD_EVENT}, + "headersAndExplicitPayload": {"target": HEADERS_AND_EXPLICIT_PAYLOAD_EVENT}, + "headersAndImplicitPayload": {"target": HEADERS_AND_IMPLICIT_PAYLOAD_EVENT}, + "error": {"target": ERROR_EVENT}, + }, +) + +DUPLEX_STREAM_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DuplexStreamInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "stream": { + "target": EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +DUPLEX_STREAM_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DuplexStreamOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "stream": { + "target": EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +DUPLEX_STREAM = Schema( + id=ShapeID("aws.protocoltests.restjson#DuplexStream"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"method": "POST", "uri": "/DuplexStream"}), + ), + Trait.new( + id=ShapeID("smithy.test#eventStreamTests"), + value=( + MappingProxyType( + { + "id": "DuplexBooleanHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"booleanHeader": True} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgC4J9Ws", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexByteHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + {"headers": MappingProxyType({"byteHeader": 1})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "byteHeader": MappingProxyType({"byte": 1}), + } + ), + "bytes": "AAAASQAAADlvxG1ZDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKYnl0ZUhlYWRlcgIBKFTmjg==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexShortHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"shortHeader": 2} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "shortHeader": MappingProxyType( + {"short": 2} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMLc2hvcnRIZWFkZXIDAAL1ETsK", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexIntegerHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + {"headers": MappingProxyType({"intHeader": 3})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "intHeader": MappingProxyType( + {"integer": 3} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMJaW50SGVhZGVyBAAAAAPlyUrb", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexLongHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"longHeader": 4294967294} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "longHeader": MappingProxyType( + {"long": 4294967294} + ), + } + ), + "bytes": "AAAAUAAAAEAr7VEyDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKbG9uZ0hlYWRlcgUAAAAA/////udnd/I=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexBlobHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"blobHeader": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "blobHeader": MappingProxyType( + {"blob": "Zm9v"} + ), + } + ), + "bytes": "AAAATQAAAD2dKQ+ADTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKYmxvYkhlYWRlcgYAA2Zvb5sbbGM=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexStringHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"stringHeader": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "stringHeader": MappingProxyType( + {"string": "foo"} + ), + } + ), + "bytes": "AAAATwAAAD8J5z3MDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMMc3RyaW5nSGVhZGVyBwADZm9vxT+2MA==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexTimestampHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + { + "timestampHeader": "2024-10-31T14:15:14Z" + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "timestampHeader": MappingProxyType( + {"timestamp": "2024-10-31T14:15:14Z"} + ), + } + ), + "bytes": "AAAAVQAAAEWTZyrNDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMPdGltZXN0YW1wSGVhZGVyCAAAAZLi7jFQ6uV3Eg==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexMultipleHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + { + "booleanHeader": True, + "stringHeader": "foo", + "blobHeader": "bar", + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + "stringHeader": MappingProxyType( + {"string": "foo"} + ), + "blobHeader": MappingProxyType( + {"blob": "YmFy"} + ), + } + ), + "bytes": "AAAAbwAAAF+FlHOQDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgAMc3RyaW5nSGVhZGVyBwADZm9vCmJsb2JIZWFkZXIGAANiYXIDXbo7", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexStringPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "stringPayload": MappingProxyType( + {"payload": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "stringPayload"} + ), + ":content-type": MappingProxyType( + {"string": "text/plain"} + ), + } + ), + "body": "foo", + "bodyMediaType": "text/plain", + "bytes": "AAAAYAAAAE30fZUJDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcADXN0cmluZ1BheWxvYWQNOmNvbnRlbnQtdHlwZQcACnRleHQvcGxhaW5mb29G1ELr", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexBlobPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "blobPayload": MappingProxyType( + {"payload": "bar"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "blobPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/octet-stream"} + ), + } + ), + "body": "bar", + "bodyMediaType": "application/octet-stream", + "bytes": "AAAAbAAAAFkrV6x1DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAC2Jsb2JQYXlsb2FkDTpjb250ZW50LXR5cGUHABhhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1iYXJv5nGJ", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexStructurePayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "structurePayload": MappingProxyType( + { + "payload": MappingProxyType( + {"structureMember": "foo"} + ) + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "structurePayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"structureMember":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAfwAAAFacqFy2DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAEHN0cnVjdHVyZVBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257InN0cnVjdHVyZU1lbWJlciI6ImZvbyJ9rcIRVA==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexUnionPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "unionPayload": MappingProxyType( + { + "payload": MappingProxyType( + {"unionMember": "bar"} + ) + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "unionPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"unionMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdwAAAFKrtdNuDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcADHVuaW9uUGF5bG9hZA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbnsidW5pb25NZW1iZXIiOiJiYXIifcZDMD4=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexHeadersAndExplicitPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifTafKXs=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexHeadersAndImplicitPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndImplicitPayload": MappingProxyType( + {"header": "foo", "payload": "bar"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headersAndImplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"payload":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAjQAAAGxoUIY5DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRJbXBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJwYXlsb2FkIjoiYmFyIn15lZtT", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexServerErrorInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + {"error": MappingProxyType({"message": "foo"})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "exception"} + ), + ":exception-type": MappingProxyType( + {"string": "error"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"message":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdAAAAFObEpkoDTptZXNzYWdlLXR5cGUHAAlleGNlcHRpb24POmV4Y2VwdGlvbi10eXBlBwAFZXJyb3INOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257Im1lc3NhZ2UiOiJmb28ifTua1S8=", + } + ), + ), + "expectation": MappingProxyType( + { + "failure": MappingProxyType( + {"errorId": "aws.protocoltests.restjson#ErrorEvent"} + ) + } + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "DuplexClientErrorInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + {"error": MappingProxyType({"message": "foo"})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "exception"} + ), + ":exception-type": MappingProxyType( + {"string": "error"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"message":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdAAAAFObEpkoDTptZXNzYWdlLXR5cGUHAAlleGNlcHRpb24POmV4Y2VwdGlvbi10eXBlBwAFZXJyb3INOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257Im1lc3NhZ2UiOiJmb28ifTua1S8=", + } + ), + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "DuplexServerUnexpectedErrorInput", + "documentation": "Servers must be able to handle structured, but unmodeled errors.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "error"} + ), + ":error-code": MappingProxyType( + {"string": "internal-error"} + ), + ":error-message": MappingProxyType( + {"string": "An unknown error occurred."} + ), + } + ), + "bytes": "AAAAbwAAAF+FlHOQDTptZXNzYWdlLXR5cGUHAAVlcnJvcgs6ZXJyb3ItY29kZQcADmludGVybmFsLWVycm9yDjplcnJvci1tZXNzYWdlBwAaQW4gdW5rbm93biBlcnJvciBvY2N1cnJlZC4kun0t", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "DuplexMissingMessageTypeInput", + "documentation": "Servers must reject events that don't contain a :message-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAfwAAAFacqFy2CzpldmVudC10eXBlBwAZaGVhZGVyc0FuZEV4cGxpY2l0UGF5bG9hZA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbgZoZWFkZXIHAANmb297InN0cnVjdHVyZU1lbWJlciI6ImJhciJ98LexJg==", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "DuplexMalformedMessageTypeInput", + "documentation": "Servers must reject events that contain a malformed :message-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"blob": "ZXZlbnQ="} + ), + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUGAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifVwdfzU=", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "DuplexMissingEventTypeInput", + "documentation": "Servers must reject message events that don't contain an :event-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAbQAAAER1MekcDTptZXNzYWdlLXR5cGUHAAVldmVudA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbgZoZWFkZXIHAANmb297InN0cnVjdHVyZU1lbWJlciI6ImJhciJ9riy0Gg==", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "DuplexMalformedEventTypeInput", + "documentation": "Servers must reject message events that contain a malformed :event-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + { + "blob": "aGVhZGVyc0FuZEV4cGxpY2l0UGF5bG9hZA==" + } + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQYAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifcP6KLk=", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "DuplexBooleanHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"booleanHeader": True} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgC4J9Ws", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexByteHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + {"headers": MappingProxyType({"byteHeader": 1})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "byteHeader": MappingProxyType({"byte": 1}), + } + ), + "bytes": "AAAASQAAADlvxG1ZDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKYnl0ZUhlYWRlcgIBKFTmjg==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexShortHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"shortHeader": 2} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "shortHeader": MappingProxyType( + {"short": 2} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMLc2hvcnRIZWFkZXIDAAL1ETsK", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexIntegerHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + {"headers": MappingProxyType({"intHeader": 3})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "intHeader": MappingProxyType( + {"integer": 3} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMJaW50SGVhZGVyBAAAAAPlyUrb", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexLongHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"longHeader": 4294967294} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "longHeader": MappingProxyType( + {"long": 4294967294} + ), + } + ), + "bytes": "AAAAUAAAAEAr7VEyDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKbG9uZ0hlYWRlcgUAAAAA/////udnd/I=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexBlobHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"blobHeader": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "blobHeader": MappingProxyType( + {"blob": "Zm9v"} + ), + } + ), + "bytes": "AAAATQAAAD2dKQ+ADTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKYmxvYkhlYWRlcgYAA2Zvb5sbbGM=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexStringHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"stringHeader": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "stringHeader": MappingProxyType( + {"string": "foo"} + ), + } + ), + "bytes": "AAAATwAAAD8J5z3MDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMMc3RyaW5nSGVhZGVyBwADZm9vxT+2MA==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexTimestampHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + { + "timestampHeader": "2024-10-31T14:15:14Z" + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "timestampHeader": MappingProxyType( + {"timestamp": "2024-10-31T14:15:14Z"} + ), + } + ), + "bytes": "AAAAVQAAAEWTZyrNDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMPdGltZXN0YW1wSGVhZGVyCAAAAZLi7jFQ6uV3Eg==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexMultipleHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + { + "booleanHeader": True, + "stringHeader": "foo", + "blobHeader": "bar", + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + "stringHeader": MappingProxyType( + {"string": "foo"} + ), + "blobHeader": MappingProxyType( + {"blob": "YmFy"} + ), + } + ), + "bytes": "AAAAbwAAAF+FlHOQDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgAMc3RyaW5nSGVhZGVyBwADZm9vCmJsb2JIZWFkZXIGAANiYXIDXbo7", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexStringPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "stringPayload": MappingProxyType( + {"payload": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "stringPayload"} + ), + ":content-type": MappingProxyType( + {"string": "text/plain"} + ), + } + ), + "body": "foo", + "bodyMediaType": "text/plain", + "bytes": "AAAAYAAAAE30fZUJDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcADXN0cmluZ1BheWxvYWQNOmNvbnRlbnQtdHlwZQcACnRleHQvcGxhaW5mb29G1ELr", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexBlobPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "blobPayload": MappingProxyType( + {"payload": "bar"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "blobPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/octet-stream"} + ), + } + ), + "body": "bar", + "bodyMediaType": "application/octet-stream", + "bytes": "AAAAbAAAAFkrV6x1DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAC2Jsb2JQYXlsb2FkDTpjb250ZW50LXR5cGUHABhhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1iYXJv5nGJ", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexStructurePayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "structurePayload": MappingProxyType( + { + "payload": MappingProxyType( + {"structureMember": "foo"} + ) + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "structurePayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"structureMember":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAfwAAAFacqFy2DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAEHN0cnVjdHVyZVBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257InN0cnVjdHVyZU1lbWJlciI6ImZvbyJ9rcIRVA==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexUnionPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "unionPayload": MappingProxyType( + { + "payload": MappingProxyType( + {"unionMember": "bar"} + ) + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "unionPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"unionMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdwAAAFKrtdNuDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcADHVuaW9uUGF5bG9hZA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbnsidW5pb25NZW1iZXIiOiJiYXIifcZDMD4=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexHeadersAndExplicitPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifTafKXs=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexHeadersAndImplicitPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndImplicitPayload": MappingProxyType( + {"header": "foo", "payload": "bar"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headersAndImplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"payload":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAjQAAAGxoUIY5DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRJbXBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJwYXlsb2FkIjoiYmFyIn15lZtT", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "DuplexServerErrorOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + {"error": MappingProxyType({"message": "foo"})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "exception"} + ), + ":exception-type": MappingProxyType( + {"string": "error"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"message":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdAAAAFObEpkoDTptZXNzYWdlLXR5cGUHAAlleGNlcHRpb24POmV4Y2VwdGlvbi10eXBlBwAFZXJyb3INOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257Im1lc3NhZ2UiOiJmb28ifTua1S8=", + } + ), + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "DuplexClientErrorOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + {"error": MappingProxyType({"message": "foo"})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "exception"} + ), + ":exception-type": MappingProxyType( + {"string": "error"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"message":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdAAAAFObEpkoDTptZXNzYWdlLXR5cGUHAAlleGNlcHRpb24POmV4Y2VwdGlvbi10eXBlBwAFZXJyb3INOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257Im1lc3NhZ2UiOiJmb28ifTua1S8=", + } + ), + ), + "expectation": MappingProxyType( + { + "failure": MappingProxyType( + {"errorId": "aws.protocoltests.restjson#ErrorEvent"} + ) + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "DuplexClientUnexpectedErrorOutput", + "documentation": "Clients must be able to handle structured, but unmodeled errors.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "error"} + ), + ":error-code": MappingProxyType( + {"string": "internal-error"} + ), + ":error-message": MappingProxyType( + {"string": "An unknown error occurred."} + ), + } + ), + "bytes": "AAAAbwAAAF+FlHOQDTptZXNzYWdlLXR5cGUHAAVlcnJvcgs6ZXJyb3ItY29kZQcADmludGVybmFsLWVycm9yDjplcnJvci1tZXNzYWdlBwAaQW4gdW5rbm93biBlcnJvciBvY2N1cnJlZC4kun0t", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "DuplexMissingMessageTypeOutput", + "documentation": "Clients must reject events that don't contain a :message-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAfwAAAFacqFy2CzpldmVudC10eXBlBwAZaGVhZGVyc0FuZEV4cGxpY2l0UGF5bG9hZA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbgZoZWFkZXIHAANmb297InN0cnVjdHVyZU1lbWJlciI6ImJhciJ98LexJg==", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "DuplexMalformedMessageTypeOutput", + "documentation": "Client must reject events that contain a malformed :message-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"blob": "ZXZlbnQ="} + ), + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUGAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifVwdfzU=", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "DuplexMissingEventTypeOutput", + "documentation": "Clients must reject message events that don't contain an :event-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAbQAAAER1MekcDTptZXNzYWdlLXR5cGUHAAVldmVudA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbgZoZWFkZXIHAANmb297InN0cnVjdHVyZU1lbWJlciI6ImJhciJ9riy0Gg==", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "DuplexMalformedEventTypeOutput", + "documentation": "Clients must reject message events that contain a malformed :event-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + { + "blob": "aGVhZGVyc0FuZEV4cGxpY2l0UGF5bG9hZA==" + } + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQYAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifcP6KLk=", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +DUPLEX_STREAM_WITH_DISTINCT_STREAMS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DuplexStreamWithDistinctStreamsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "stream": { + "target": EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +SINGLETON_EVENT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SingletonEvent"), + members={"value": {"target": STRING}}, +) + +SINGLETON_EVENT_STREAM = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SingletonEventStream"), + shape_type=ShapeType.UNION, + members={"singleton": {"target": SINGLETON_EVENT}}, +) + +DUPLEX_STREAM_WITH_DISTINCT_STREAMS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DuplexStreamWithDistinctStreamsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "stream": { + "target": SINGLETON_EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +DUPLEX_STREAM_WITH_DISTINCT_STREAMS = Schema( + id=ShapeID("aws.protocoltests.restjson#DuplexStreamWithDistinctStreams"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/DuplexStreamWithDistinctStreams"} + ), + ) + ], +) + +DUPLEX_STREAM_WITH_INITIAL_MESSAGES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DuplexStreamWithInitialMessagesInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "initialRequestMember": { + "target": STRING, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="initial-request-member" + ), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "stream": { + "target": EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +DUPLEX_STREAM_WITH_INITIAL_MESSAGES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#DuplexStreamWithInitialMessagesOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "initialResponseMember": { + "target": STRING, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="initial-response-member" + ), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "stream": { + "target": EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +SERVICE_UNAVAILABLE_ERROR = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ServiceUnavailableError"), + traits=[ + Trait.new(id=ShapeID("smithy.api#error"), value="server"), + Trait.new(id=ShapeID("smithy.api#httpError"), value=500), + ], + members={"message": {"target": STRING}}, +) + +DUPLEX_STREAM_WITH_INITIAL_MESSAGES = Schema( + id=ShapeID("aws.protocoltests.restjson#DuplexStreamWithInitialMessages"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/DuplexStreamWithInitialMessages"} + ), + ), + Trait.new( + id=ShapeID("smithy.test#eventStreamTests"), + value=( + MappingProxyType( + { + "id": "DuplexInitialRequestInput", + "protocol": "aws.protocols#restJson1", + "initialRequestParams": MappingProxyType( + {"initialRequestMember": "foo"} + ), + "initialRequest": MappingProxyType( + { + "method": "POST", + "uri": "/DuplexStreamWithInitialMessages", + "headers": MappingProxyType( + {"initial-request-member": "foo"} + ), + } + ), + "initialRequestShape": "smithy.test#InitialHttpRequest", + } + ), + MappingProxyType( + { + "id": "DuplexMissingRequiredInitialRequestInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"booleanHeader": True} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgC4J9Ws", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "DuplexInitialResponseOutput", + "protocol": "aws.protocols#restJson1", + "initialResponseParams": MappingProxyType( + {"initialResponseMember": "foo"} + ), + "initialResponse": MappingProxyType( + { + "code": 200, + "headers": MappingProxyType( + {"initial-response-member": "foo"} + ), + } + ), + "initialResponseShape": "smithy.test#InitialHttpResponse", + } + ), + MappingProxyType( + { + "id": "DuplexMissingRequiredInitialResponseOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"booleanHeader": True} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgC4J9Ws", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "DuplexModeledProtocolError", + "protocol": "aws.protocols#restJson1", + "initialResponse": MappingProxyType( + { + "code": 500, + "headers": MappingProxyType( + { + "Content-Type": "application/json", + "X-Amzn-Errortype": "ServiceUnavailableError", + } + ), + "body": '{"message": "foo"}', + "bodyMediaType": "application/json", + } + ), + "initialResponseShape": "smithy.test#InitialHttpResponse", + "expectation": MappingProxyType( + { + "failure": MappingProxyType( + { + "errorId": "aws.protocoltests.restjson#ServiceUnavailableError" + } + ) + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "DuplexUnmodeledProtocolError", + "protocol": "aws.protocols#restJson1", + "initialResponse": MappingProxyType( + { + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "text/plain"} + ), + "body": "service unavailable", + "bodyMediaType": "text/plain", + } + ), + "initialResponseShape": "smithy.test#InitialHttpResponse", + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#EmptyInputAndEmptyOutputInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], +) + +EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#EmptyInputAndEmptyOutputOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], +) + +EMPTY_INPUT_AND_EMPTY_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.restjson#EmptyInputAndEmptyOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonEmptyInputAndEmptyOutput", + "documentation": "Clients should not serialize a JSON payload when no parameters\nare given that are sent in the body. A service will tolerate\nclients that omit a payload or that send a JSON object.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/EmptyInputAndEmptyOutput", + "body": "", + } + ), + MappingProxyType( + { + "id": "RestJsonEmptyInputAndEmptyOutputWithJson", + "documentation": "Similar to RestJsonEmptyInputAndEmptyOutput, but ensures that\nservices gracefully handles receiving a JSON object.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/EmptyInputAndEmptyOutput", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": "{}", + "bodyMediaType": "application/json", + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonEmptyInputAndEmptyOutput", + "documentation": "As of January 2021, server implementations are expected to\nrespond with a JSON object regardless of if the output\nparameters are empty.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": "{}", + "bodyMediaType": "application/json", + } + ), + MappingProxyType( + { + "id": "RestJsonEmptyInputAndEmptyOutputJsonObjectOutput", + "documentation": "This test ensures that clients can gracefully handle\nsituations where a service omits a JSON payload entirely.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "", + "appliesTo": "client", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/EmptyInputAndEmptyOutput", "method": "POST"} + ), + ), + ], +) + +ENDPOINT_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#EndpointOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +ENDPOINT_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#EndpointOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +ENDPOINT_OPERATION = Schema( + id=ShapeID("aws.protocoltests.restjson#EndpointOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonEndpointTrait", + "documentation": "Operations can prepend to the given host if they define the\nendpoint trait.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/EndpointOperation", + "body": "", + "host": "example.com", + "resolvedHost": "foo.example.com", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#endpoint"), + value=MappingProxyType({"hostPrefix": "foo."}), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/EndpointOperation", "method": "POST"}), + ), + ], +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#EndpointWithHostLabelOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HostLabelInput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "label": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#hostLabel")), + Trait.new(id=ShapeID("smithy.api#required")), + ], + } + }, +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#EndpointWithHostLabelOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +ENDPOINT_WITH_HOST_LABEL_OPERATION = Schema( + id=ShapeID("aws.protocoltests.restjson#EndpointWithHostLabelOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonEndpointTraitWithHostLabel", + "documentation": "Operations can prepend to the given host if they define the\nendpoint trait, and can use the host label trait to define\nfurther customization based on user input.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/EndpointWithHostLabelOperation", + "body": '{"label": "bar"}', + "bodyMediaType": "application/json", + "host": "example.com", + "resolvedHost": "foo.bar.example.com", + "params": MappingProxyType({"label": "bar"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#endpoint"), + value=MappingProxyType({"hostPrefix": "foo.{label}."}), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/EndpointWithHostLabelOperation", "method": "POST"} + ), + ), + ], +) + +FINITE_STREAMING_BLOB = Schema( + id=ShapeID("aws.protocoltests.restjson#FiniteStreamingBlob"), + shape_type=ShapeType.BLOB, + traits=[ + Trait.new(id=ShapeID("smithy.api#streaming")), + Trait.new(id=ShapeID("smithy.api#requiresLength")), + ], +) + +FOO_ERROR = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#FooError"), + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonFooErrorUsingXAmznErrorType", + "documentation": "Serializes the X-Amzn-ErrorType header. For an example service, see Amazon EKS.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType({"X-Amzn-Errortype": "FooError"}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorUsingXAmznErrorTypeWithUri", + "documentation": "Some X-Amzn-Errortype headers contain URLs. Clients need to split the URL on ':' and take only the first half of the string. For example, 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/'\nis to be interpreted as 'ValidationException'.\n\nFor an example service see Amazon Polly.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + { + "X-Amzn-Errortype": "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorUsingXAmznErrorTypeWithUriAndNamespace", + "documentation": "X-Amzn-Errortype might contain a URL and a namespace. Client should extract only the shape name. This is a pathalogical case that might not actually happen in any deployed AWS service.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + { + "X-Amzn-Errortype": "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorUsingXAmznErrorTypeWithUriAndDifferentNamespace", + "documentation": "Because namespace and URL are ignored, an unrecognized namespace should not make a difference.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + { + "X-Amzn-Errortype": "aws.different.namespace#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/" + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorUsingCode", + "documentation": "This example uses the 'code' property in the output rather than X-Amzn-Errortype. Some services do this though it's preferable to send the X-Amzn-Errortype. Client implementations must first check for the X-Amzn-Errortype and then check for a top-level 'code' property.\n\nFor example service see Amazon S3 Glacier.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "code": "FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorUsingCodeAndNamespace", + "documentation": "Some services serialize errors using code, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "code": "aws.protocoltests.restjson#FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorUsingCodeUriAndNamespace", + "documentation": "Some services serialize errors using code, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "code": "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorWithDunderType", + "documentation": "Some services serialize errors using __type.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "__type": "FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorWithDunderTypeAndNamespace", + "documentation": "Some services serialize errors using __type, and it might contain a namespace. Clients should just take the last part of the string after '#'.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "__type": "aws.protocoltests.restjson#FooError"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorWithDunderTypeUriAndNamespace", + "documentation": "Some services serialize errors using __type, and it might contain a namespace. It also might contain a URI. Clients should just take the last part of the string after '#' and before \":\". This is a pathalogical case that might not occur in any deployed AWS service.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "__type": "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonFooErrorWithNestedTypeProperty", + "documentation": "Some services serialize errors using __type, and if the response includes additional shapes that belong to a different namespace there'll be a nested __type property that must not be considered when determining which error to be surfaced.\n\nFor an example service see Amazon DynamoDB.", + "protocol": "aws.protocols#restJson1", + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "__type": "aws.protocoltests.restjson#FooError",\n "ErrorDetails": [\n {\n "__type": "com.amazon.internal#ErrorDetails",\n "reason": "Some reason"\n }\n ]\n}', + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="server"), + Trait.new(id=ShapeID("smithy.api#httpError"), value=500), + ], +) + +FRACTIONAL_SECONDS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#FractionalSecondsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +FRACTIONAL_SECONDS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#FractionalSecondsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={"datetime": {"target": DATE_TIME}}, +) + +FRACTIONAL_SECONDS = Schema( + id=ShapeID("aws.protocoltests.restjson#FractionalSeconds"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonDateTimeWithFractionalSeconds", + "documentation": "Ensures that clients can correctly parse datetime timestamps with fractional seconds", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": ' {\n "datetime": "2000-01-02T20:34:56.123Z"\n }\n', + "params": MappingProxyType({"datetime": 9.46845296123e8}), + "bodyMediaType": "application/json", + "appliesTo": "client", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/FractionalSeconds", "method": "POST"}), + ), + ], +) + +GREETING_WITH_ERRORS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#GreetingWithErrorsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +GREETING_WITH_ERRORS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#GreetingWithErrorsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "greeting": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Greeting") + ], + } + }, +) + +INVALID_GREETING = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#InvalidGreeting"), + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonInvalidGreetingError", + "documentation": "Parses simple JSON errors", + "protocol": "aws.protocols#restJson1", + "params": MappingProxyType({"Message": "Hi"}), + "code": 400, + "headers": MappingProxyType( + { + "Content-Type": "application/json", + "X-Amzn-Errortype": "InvalidGreeting", + } + ), + "body": '{\n "Message": "Hi"\n}', + "bodyMediaType": "application/json", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#error"), value="client"), + Trait.new(id=ShapeID("smithy.api#httpError"), value=400), + ], + members={"Message": {"target": STRING}}, +) + +GREETING_WITH_ERRORS = Schema( + id=ShapeID("aws.protocoltests.restjson#GreetingWithErrors"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonGreetingWithErrors", + "documentation": "Ensures that operations with errors successfully know how\nto deserialize a successful response. As of January 2021,\nserver implementations are expected to respond with a\nJSON object regardless of if the output parameters are\nempty.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType({"X-Greeting": "Hello"}), + "params": MappingProxyType({"greeting": "Hello"}), + } + ), + MappingProxyType( + { + "id": "RestJsonGreetingWithErrorsNoPayload", + "documentation": "This test is similar to RestJsonGreetingWithErrors, but it\nensures that clients can gracefully deal with a server\nomitting a response payload.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "", + "headers": MappingProxyType({"X-Greeting": "Hello"}), + "params": MappingProxyType({"greeting": "Hello"}), + "appliesTo": "client", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/GreetingWithErrors", "method": "PUT"}), + ), + ], +) + +HOST_WITH_PATH_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HostWithPathOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +HOST_WITH_PATH_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HostWithPathOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HOST_WITH_PATH_OPERATION = Schema( + id=ShapeID("aws.protocoltests.restjson#HostWithPathOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHostWithPath", + "documentation": "Custom endpoints supplied by users can have paths", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/custom/HostWithPathOperation", + "body": "", + "host": "example.com/custom", + "appliesTo": "client", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/HostWithPathOperation", "method": "GET"}), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +HTTP_CHECKSUM_REQUIRED_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpChecksumRequiredInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpChecksumRequiredInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"foo": {"target": STRING}}, +) + +HTTP_CHECKSUM_REQUIRED_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpChecksumRequiredOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpChecksumRequiredInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"foo": {"target": STRING}}, +) + +HTTP_CHECKSUM_REQUIRED = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpChecksumRequired"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpChecksumRequired", + "documentation": "Adds Content-MD5 header", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/HttpChecksumRequired", + "body": '{\n "foo":"base64 encoded md5 checksum"\n}\n', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/json", + "Content-MD5": "iB0/3YSo7maijL0IGOgA9g==", + } + ), + "params": MappingProxyType( + {"foo": "base64 encoded md5 checksum"} + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/HttpChecksumRequired", "method": "POST"}), + ), + Trait.new(id=ShapeID("smithy.api#httpChecksumRequired")), + ], +) + +STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#StringMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +HTTP_EMPTY_PREFIX_HEADERS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpEmptyPrefixHeadersInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "prefixHeaders": { + "target": STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPrefixHeaders"), value="")], + }, + "specificHeader": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="hello")], + }, + }, +) + +HTTP_EMPTY_PREFIX_HEADERS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpEmptyPrefixHeadersOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "prefixHeaders": { + "target": STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPrefixHeaders"), value="")], + }, + "specificHeader": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="hello")], + }, + }, +) + +HTTP_EMPTY_PREFIX_HEADERS = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpEmptyPrefixHeaders"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpEmptyPrefixHeadersRequestClient", + "documentation": "Serializes all request headers, using specific when present", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/HttpEmptyPrefixHeaders", + "body": "", + "headers": MappingProxyType({"x-foo": "Foo", "hello": "There"}), + "params": MappingProxyType( + { + "prefixHeaders": MappingProxyType( + {"x-foo": "Foo", "hello": "Hello"} + ), + "specificHeader": "There", + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonHttpEmptyPrefixHeadersRequestServer", + "documentation": "Deserializes all request headers with the same for prefix and specific", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/HttpEmptyPrefixHeaders", + "body": "", + "headers": MappingProxyType({"x-foo": "Foo", "hello": "There"}), + "params": MappingProxyType( + { + "prefixHeaders": MappingProxyType( + {"x-foo": "Foo", "hello": "There"} + ), + "specificHeader": "There", + } + ), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpEmptyPrefixHeadersResponseClient", + "documentation": "Deserializes all response headers with the same for prefix and specific", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType({"x-foo": "Foo", "hello": "There"}), + "params": MappingProxyType( + { + "prefixHeaders": MappingProxyType( + {"x-foo": "Foo", "hello": "There"} + ), + "specificHeader": "There", + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonHttpEmptyPrefixHeadersResponseServer", + "documentation": "Serializes all response headers, using specific when present", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType({"x-foo": "Foo", "hello": "There"}), + "params": MappingProxyType( + { + "prefixHeaders": MappingProxyType( + {"x-foo": "Foo", "hello": "Hello"} + ), + "specificHeader": "There", + } + ), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/HttpEmptyPrefixHeaders", "method": "GET"}), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +STRING_ENUM = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StringEnum"), + shape_type=ShapeType.ENUM, + members={ + "V": { + "target": UNIT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#enumValue"), value="enumvalue") + ], + } + }, +) + +HTTP_ENUM_PAYLOAD_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpEnumPayloadInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#EnumPayloadInput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "payload": { + "target": STRING_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +HTTP_ENUM_PAYLOAD_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpEnumPayloadOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#EnumPayloadInput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "payload": { + "target": STRING_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +HTTP_ENUM_PAYLOAD = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpEnumPayload"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonEnumPayloadRequest", + "uri": "/EnumPayload", + "headers": MappingProxyType({"Content-Type": "text/plain"}), + "body": "enumvalue", + "params": MappingProxyType({"payload": "enumvalue"}), + "method": "POST", + "protocol": "aws.protocols#restJson1", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonEnumPayloadResponse", + "headers": MappingProxyType({"Content-Type": "text/plain"}), + "body": "enumvalue", + "params": MappingProxyType({"payload": "enumvalue"}), + "protocol": "aws.protocols#restJson1", + "code": 200, + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/EnumPayload", "method": "POST"}), + ), + ], +) + +HTTP_PAYLOAD_TRAITS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadTraitsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpPayloadTraitsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "blob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +HTTP_PAYLOAD_TRAITS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadTraitsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpPayloadTraitsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "blob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +HTTP_PAYLOAD_TRAITS = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadTraits"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPayloadTraitsWithBlob", + "documentation": "Serializes a blob in the HTTP payload", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/HttpPayloadTraits", + "body": "blobby blob blob", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"Content-Type": "application/octet-stream", "X-Foo": "Foo"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"foo": "Foo", "blob": "blobby blob blob"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPayloadTraitsWithNoBlobBody", + "documentation": "Serializes an empty blob in the HTTP payload", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/HttpPayloadTraits", + "body": "", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType({"X-Foo": "Foo"}), + "params": MappingProxyType({"foo": "Foo"}), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPayloadTraitsWithBlobAcceptsAllContentTypes", + "documentation": "Servers must accept any content type for blob inputs\nwithout the media type trait.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/HttpPayloadTraits", + "body": "This is definitely a jpeg", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"X-Foo": "Foo", "Content-Type": "image/jpeg"} + ), + "params": MappingProxyType( + {"foo": "Foo", "blob": "This is definitely a jpeg"} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPayloadTraitsWithBlobAcceptsNoContentType", + "documentation": "Servers must accept no content type for blob inputs\nwithout the media type trait.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/HttpPayloadTraits", + "body": "This is definitely a jpeg", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType({"X-Foo": "Foo"}), + "params": MappingProxyType( + {"foo": "Foo", "blob": "This is definitely a jpeg"} + ), + "appliesTo": "server", + "tags": ("content-type",), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPayloadTraitsWithBlobAcceptsAllAccepts", + "documentation": "Servers must accept any accept header for blob inputs\nwithout the media type trait.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/HttpPayloadTraits", + "body": "This is definitely a jpeg", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"X-Foo": "Foo", "Accept": "image/jpeg"} + ), + "params": MappingProxyType( + {"foo": "Foo", "blob": "This is definitely a jpeg"} + ), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPayloadTraitsWithBlob", + "documentation": "Serializes a blob in the HTTP payload", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "blobby blob blob", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType({"X-Foo": "Foo"}), + "params": MappingProxyType( + {"foo": "Foo", "blob": "blobby blob blob"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPayloadTraitsWithNoBlobBody", + "documentation": "Serializes an empty blob in the HTTP payload", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType({"X-Foo": "Foo"}), + "params": MappingProxyType({"foo": "Foo"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/HttpPayloadTraits", "method": "POST"}), + ), + ], +) + +TEXT_PLAIN_BLOB = Schema( + id=ShapeID("aws.protocoltests.shared#TextPlainBlob"), + shape_type=ShapeType.BLOB, + traits=[Trait.new(id=ShapeID("smithy.api#mediaType"), value="text/plain")], +) + +HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadTraitsWithMediaTypeInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpPayloadTraitsWithMediaTypeInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "blob": { + "target": TEXT_PLAIN_BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadTraitsWithMediaTypeOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpPayloadTraitsWithMediaTypeInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "blob": { + "target": TEXT_PLAIN_BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadTraitsWithMediaType"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPayloadTraitsWithMediaTypeWithBlob", + "documentation": "Serializes a blob in the HTTP payload with a content-type", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/HttpPayloadTraitsWithMediaType", + "body": "blobby blob blob", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"X-Foo": "Foo", "Content-Type": "text/plain"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"foo": "Foo", "blob": "blobby blob blob"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPayloadTraitsWithMediaTypeWithBlob", + "documentation": "Serializes a blob in the HTTP payload with a content-type", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "blobby blob blob", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"X-Foo": "Foo", "Content-Type": "text/plain"} + ), + "params": MappingProxyType( + {"foo": "Foo", "blob": "blobby blob blob"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/HttpPayloadTraitsWithMediaType", "method": "POST"} + ), + ), + ], +) + +NESTED_PAYLOAD = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NestedPayload"), + members={"greeting": {"target": STRING}, "name": {"target": STRING}}, +) + +HTTP_PAYLOAD_WITH_STRUCTURE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadWithStructureInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpPayloadWithStructureInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "nested": { + "target": NESTED_PAYLOAD, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +HTTP_PAYLOAD_WITH_STRUCTURE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadWithStructureOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpPayloadWithStructureInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "nested": { + "target": NESTED_PAYLOAD, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +HTTP_PAYLOAD_WITH_STRUCTURE = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadWithStructure"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPayloadWithStructure", + "documentation": "Serializes a structure in the payload", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/HttpPayloadWithStructure", + "body": '{\n "greeting": "hello",\n "name": "Phreddy"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + { + "nested": MappingProxyType( + {"greeting": "hello", "name": "Phreddy"} + ) + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPayloadWithStructure", + "documentation": "Serializes a structure in the payload", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "greeting": "hello",\n "name": "Phreddy"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "nested": MappingProxyType( + {"greeting": "hello", "name": "Phreddy"} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPayloadWithStructureAndEmptyResponseBody", + "documentation": "Serializes a structure in the payload", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "", + "params": MappingProxyType({"nested": None}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/HttpPayloadWithStructure", "method": "PUT"} + ), + ), + ], +) + +UNION_PAYLOAD = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#UnionPayload"), + shape_type=ShapeType.UNION, + members={"greeting": {"target": STRING}}, +) + +HTTP_PAYLOAD_WITH_UNION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadWithUnionInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpPayloadWithUnionInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "nested": { + "target": UNION_PAYLOAD, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +HTTP_PAYLOAD_WITH_UNION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadWithUnionOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpPayloadWithUnionInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "nested": { + "target": UNION_PAYLOAD, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +HTTP_PAYLOAD_WITH_UNION = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpPayloadWithUnion"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPayloadWithUnion", + "documentation": "Serializes a union in the payload.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/HttpPayloadWithUnion", + "body": '{\n "greeting": "hello"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"nested": MappingProxyType({"greeting": "hello"})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPayloadWithUnsetUnion", + "documentation": "No payload is sent if the union has no value.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/HttpPayloadWithUnion", + "body": "", + "params": MappingProxyType({}), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPayloadWithUnion", + "documentation": "Serializes a union in the payload.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "greeting": "hello"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"nested": MappingProxyType({"greeting": "hello"})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPayloadWithUnsetUnion", + "documentation": "No payload is sent if the union has no value.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "", + "headers": MappingProxyType({"Content-Length": "0"}), + "params": MappingProxyType({}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/HttpPayloadWithUnion", "method": "PUT"}), + ), + ], +) + +HTTP_PREFIX_HEADERS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPrefixHeadersInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="x-foo")], + }, + "fooMap": { + "target": STRING_MAP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpPrefixHeaders"), value="x-foo-") + ], + }, + }, +) + +HTTP_PREFIX_HEADERS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPrefixHeadersOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="x-foo")], + }, + "fooMap": { + "target": STRING_MAP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpPrefixHeaders"), value="x-foo-") + ], + }, + }, +) + +HTTP_PREFIX_HEADERS = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpPrefixHeaders"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPrefixHeadersArePresent", + "documentation": "Adds headers by prefix", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/HttpPrefixHeaders", + "body": "", + "headers": MappingProxyType( + { + "x-foo": "Foo", + "x-foo-abc": "Abc value", + "x-foo-def": "Def value", + } + ), + "params": MappingProxyType( + { + "foo": "Foo", + "fooMap": MappingProxyType( + {"abc": "Abc value", "def": "Def value"} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPrefixHeadersAreNotPresent", + "documentation": "No prefix headers are serialized because the value is not present", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/HttpPrefixHeaders", + "body": "", + "headers": MappingProxyType({"x-foo": "Foo"}), + "params": MappingProxyType( + {"foo": "Foo", "fooMap": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonHttpPrefixEmptyHeaders", + "documentation": "Serialize prefix headers were the value is present but empty", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/HttpPrefixHeaders", + "body": "", + "params": MappingProxyType( + {"fooMap": MappingProxyType({"abc": ""})} + ), + "headers": MappingProxyType({"x-foo-abc": ""}), + "appliesTo": "client", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPrefixHeadersArePresent", + "documentation": "Adds headers by prefix", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + { + "x-foo": "Foo", + "x-foo-abc": "Abc value", + "x-foo-def": "Def value", + } + ), + "params": MappingProxyType( + { + "foo": "Foo", + "fooMap": MappingProxyType( + {"abc": "Abc value", "def": "Def value"} + ), + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#externalDocumentation"), + value=MappingProxyType( + { + "httpPrefixHeaders Trait": "https://smithy.io/2.0/spec/http-bindings.html#httpprefixheaders-trait" + } + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/HttpPrefixHeaders", "method": "GET"}), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +HTTP_PREFIX_HEADERS_IN_RESPONSE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPrefixHeadersInResponseInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], +) + +HTTP_PREFIX_HEADERS_IN_RESPONSE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpPrefixHeadersInResponseOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "prefixHeaders": { + "target": STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPrefixHeaders"), value="")], + } + }, +) + +HTTP_PREFIX_HEADERS_IN_RESPONSE = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpPrefixHeadersInResponse"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "HttpPrefixHeadersResponse", + "documentation": "(de)serializes all response headers", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType({"x-foo": "Foo", "hello": "Hello"}), + "params": MappingProxyType( + { + "prefixHeaders": MappingProxyType( + {"x-foo": "Foo", "hello": "Hello"} + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/HttpPrefixHeadersResponse", "method": "GET"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +QUERY_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#QueryMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +HTTP_QUERY_PARAMS_ONLY_OPERATION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpQueryParamsOnlyOperationInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#HttpQueryParamsOnlyInput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "queryMap": { + "target": QUERY_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQueryParams"))], + } + }, +) + +HTTP_QUERY_PARAMS_ONLY_OPERATION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpQueryParamsOnlyOperationOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HTTP_QUERY_PARAMS_ONLY_OPERATION = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpQueryParamsOnlyOperation"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "HttpQueryParamsOnlyRequest", + "documentation": "Test that httpQueryParams are included in request when no other query parameters exist", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/http-query-params-only", + "queryParams": ("a=b", "c=d"), + "params": MappingProxyType( + {"queryMap": MappingProxyType({"a": "b", "c": "d"})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "HttpQueryParamsOnlyEmptyRequest", + "documentation": "Test that empty httpQueryParams map results in no query parameters", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/http-query-params-only", + "params": MappingProxyType({"queryMap": MappingProxyType({})}), + "appliesTo": "client", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/http-query-params-only", "method": "GET"}), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithFloatLabelsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "float": { + "target": FLOAT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "double": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + }, +) + +HTTP_REQUEST_WITH_FLOAT_LABELS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithFloatLabelsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HTTP_REQUEST_WITH_FLOAT_LABELS = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithFloatLabels"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonSupportsNaNFloatLabels", + "documentation": "Supports handling NaN float label values.", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/FloatHttpLabels/NaN/NaN", + "body": "", + "params": MappingProxyType({"float": "NaN", "double": "NaN"}), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsInfinityFloatLabels", + "documentation": "Supports handling Infinity float label values.", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/FloatHttpLabels/Infinity/Infinity", + "body": "", + "params": MappingProxyType( + {"float": "Infinity", "double": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNegativeInfinityFloatLabels", + "documentation": "Supports handling -Infinity float label values.", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/FloatHttpLabels/-Infinity/-Infinity", + "body": "", + "params": MappingProxyType( + {"float": "-Infinity", "double": "-Infinity"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "GET", "uri": "/FloatHttpLabels/{float}/{double}"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithGreedyLabelInPathInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "foo": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "baz": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + }, +) + +HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithGreedyLabelInPathOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithGreedyLabelInPath"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpRequestWithGreedyLabelInPath", + "documentation": "Serializes greedy labels and normal labels", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/HttpRequestWithGreedyLabelInPath/foo/hello%2Fescape/baz/there/guy", + "body": "", + "params": MappingProxyType( + {"foo": "hello/escape", "baz": "there/guy"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + { + "method": "GET", + "uri": "/HttpRequestWithGreedyLabelInPath/foo/{foo}/baz/{baz+}", + } + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +HTTP_REQUEST_WITH_LABELS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithLabelsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "string": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "short": { + "target": SHORT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "integer": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "long": { + "target": LONG, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "float": { + "target": FLOAT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "double": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "boolean": { + "target": BOOLEAN, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + }, +) + +HTTP_REQUEST_WITH_LABELS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithLabelsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HTTP_REQUEST_WITH_LABELS = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithLabels"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonInputWithHeadersAndAllParams", + "documentation": "Sends a GET request that uses URI label bindings", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/HttpRequestWithLabels/string/1/2/3/4.1/5.1/true/2019-12-16T23%3A48%3A18Z", + "body": "", + "params": MappingProxyType( + { + "string": "string", + "short": 1, + "integer": 2, + "long": 3, + "float": 4.1, + "double": 5.1, + "boolean": True, + "timestamp": 1576540098, + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpRequestLabelEscaping", + "documentation": "Sends a GET request that uses URI label bindings", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/HttpRequestWithLabels/%20%25%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D%F0%9F%98%B9/1/2/3/4.1/5.1/true/2019-12-16T23%3A48%3A18Z", + "body": "", + "params": MappingProxyType( + { + "string": " %:/?#[]@!$&'()*+,;=😹", + "short": 1, + "integer": 2, + "long": 3, + "float": 4.1, + "double": 5.1, + "boolean": True, + "timestamp": 1576540098, + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + { + "method": "GET", + "uri": "/HttpRequestWithLabels/{string}/{short}/{integer}/{long}/{float}/{double}/{boolean}/{timestamp}", + } + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +EPOCH_SECONDS = Schema( + id=ShapeID("aws.protocoltests.shared#EpochSeconds"), + shape_type=ShapeType.TIMESTAMP, + traits=[Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds")], +) + +HTTP_DATE = Schema( + id=ShapeID("aws.protocoltests.shared#HttpDate"), + shape_type=ShapeType.TIMESTAMP, + traits=[Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date")], +) + +HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT = Schema.collection( + id=ShapeID( + "aws.protocoltests.restjson#HttpRequestWithLabelsAndTimestampFormatInput" + ), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "memberEpochSeconds": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ), + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "memberHttpDate": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date"), + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "memberDateTime": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time"), + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "defaultFormat": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "targetEpochSeconds": { + "target": EPOCH_SECONDS, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "targetHttpDate": { + "target": HTTP_DATE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "targetDateTime": { + "target": DATE_TIME, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + }, +) + +HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_OUTPUT = Schema.collection( + id=ShapeID( + "aws.protocoltests.restjson#HttpRequestWithLabelsAndTimestampFormatOutput" + ), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithLabelsAndTimestampFormat"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpRequestWithLabelsAndTimestampFormat", + "documentation": "Serializes different timestamp formats in URI labels", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/HttpRequestWithLabelsAndTimestampFormat/1576540098/Mon%2C%2016%20Dec%202019%2023%3A48%3A18%20GMT/2019-12-16T23%3A48%3A18Z/2019-12-16T23%3A48%3A18Z/1576540098/Mon%2C%2016%20Dec%202019%2023%3A48%3A18%20GMT/2019-12-16T23%3A48%3A18Z", + "body": "", + "params": MappingProxyType( + { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098, + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + { + "method": "GET", + "uri": "/HttpRequestWithLabelsAndTimestampFormat/{memberEpochSeconds}/{memberHttpDate}/{memberDateTime}/{defaultFormat}/{targetEpochSeconds}/{targetHttpDate}/{targetDateTime}", + } + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +HTTP_REQUEST_WITH_REGEX_LITERAL_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithRegexLiteralInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "str": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + } + }, +) + +HTTP_REQUEST_WITH_REGEX_LITERAL_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithRegexLiteralOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +HTTP_REQUEST_WITH_REGEX_LITERAL = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpRequestWithRegexLiteral"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonToleratesRegexCharsInSegments", + "documentation": "Path matching is not broken by regex expressions in literal segments", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/ReDosLiteral/abc/(a+)+", + "body": "", + "params": MappingProxyType({"str": "abc"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "GET", "uri": "/ReDosLiteral/{str}/(a+)+"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +HTTP_RESPONSE_CODE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpResponseCodeInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +HTTP_RESPONSE_CODE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpResponseCodeOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "Status": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#httpResponseCode"))], + } + }, +) + +HTTP_RESPONSE_CODE = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpResponseCode"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpResponseCode", + "documentation": "Binds the http response code to an output structure. Note that\neven though all members are bound outside of the payload, an\nempty JSON object is serialized in the response. However,\nclients should be able to handle an empty JSON object or an\nempty payload without failing to deserialize a response.", + "protocol": "aws.protocols#restJson1", + "code": 201, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": "{}", + "bodyMediaType": "application/json", + "params": MappingProxyType({"Status": 201}), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpResponseCodeDefaultsToModeledCode", + "documentation": "Binds the http response code to the http trait's code if the\ncode isn't explicitly set. A client would be parsing the\nhttp response code, so this would always be present, but\na server doesn't require it to be set to serialize a request.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": "{}", + "bodyMediaType": "application/json", + "params": MappingProxyType({}), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "RestJsonHttpResponseCodeWithNoPayload", + "documentation": "This test ensures that clients gracefully handle cases where\nthe service responds with no payload rather than an empty JSON\nobject.", + "protocol": "aws.protocols#restJson1", + "code": 201, + "body": "", + "params": MappingProxyType({"Status": 201}), + "appliesTo": "client", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/HttpResponseCode", "method": "PUT"}), + ), + ], +) + +HTTP_STRING_PAYLOAD_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpStringPayloadInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#StringPayloadInput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "payload": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +HTTP_STRING_PAYLOAD_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#HttpStringPayloadOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#StringPayloadInput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "payload": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +HTTP_STRING_PAYLOAD = Schema( + id=ShapeID("aws.protocoltests.restjson#HttpStringPayload"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonStringPayloadRequest", + "uri": "/StringPayload", + "body": "rawstring", + "bodyMediaType": "text/plain", + "headers": MappingProxyType({"Content-Type": "text/plain"}), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"payload": "rawstring"}), + "method": "POST", + "protocol": "aws.protocols#restJson1", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonStringPayloadResponse", + "headers": MappingProxyType({"Content-Type": "text/plain"}), + "body": "rawstring", + "bodyMediaType": "text/plain", + "params": MappingProxyType({"payload": "rawstring"}), + "protocol": "aws.protocols#restJson1", + "code": 200, + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonStringPayloadNoContentType", + "documentation": "Serializes a string in the HTTP payload without a content-type header", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/StringPayload", + "body": "rawstring", + } + ), + "response": MappingProxyType( + { + "code": 415, + "headers": MappingProxyType( + { + "x-amzn-errortype": "UnsupportedMediaTypeException" + } + ), + } + ), + "tags": ("content-type",), + } + ), + MappingProxyType( + { + "id": "RestJsonStringPayloadWrongContentType", + "documentation": "Serializes a string in the HTTP payload without the expected content-type header", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/StringPayload", + "body": "rawstring", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 415, + "headers": MappingProxyType( + { + "x-amzn-errortype": "UnsupportedMediaTypeException" + } + ), + } + ), + "tags": ("content-type",), + } + ), + MappingProxyType( + { + "id": "RestJsonStringPayloadUnsatisfiableAccept", + "documentation": "Serializes a string in the HTTP payload with an unstatisfiable accept header", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/StringPayload", + "body": "rawstring", + "headers": MappingProxyType( + { + "Content-Type": "text/plain", + "Accept": "application/json", + } + ), + } + ), + "response": MappingProxyType( + { + "code": 406, + "headers": MappingProxyType( + {"x-amzn-errortype": "NotAcceptableException"} + ), + } + ), + "tags": ("accept",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/StringPayload", "method": "POST"}), + ), + ], +) + +IGNORE_QUERY_PARAMS_IN_RESPONSE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#IgnoreQueryParamsInResponseInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +IGNORE_QUERY_PARAMS_IN_RESPONSE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#IgnoreQueryParamsInResponseOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "baz": { + "target": STRING, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#suppress"), + value=("HttpBindingTraitIgnored",), + ), + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="baz"), + ], + } + }, +) + +IGNORE_QUERY_PARAMS_IN_RESPONSE = Schema( + id=ShapeID("aws.protocoltests.restjson#IgnoreQueryParamsInResponse"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonIgnoreQueryParamsInResponse", + "documentation": "Query parameters must be ignored when serializing the output\nof an operation. As of January 2021, server implementations\nare expected to respond with a JSON object regardless of\nif the output parameters are empty.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{"baz":"bam"}', + "bodyMediaType": "application/json", + "params": MappingProxyType({"baz": "bam"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/IgnoreQueryParamsInResponse", "method": "GET"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +INPUT_AND_OUTPUT_WITH_HEADERS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#InputAndOutputWithHeadersInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#InputAndOutputWithHeadersIO", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "headerString": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-String") + ], + }, + "headerByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Byte")], + }, + "headerShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Short")], + }, + "headerInteger": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Integer") + ], + }, + "headerLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Long")], + }, + "headerFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Float")], + }, + "headerDouble": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Double") + ], + }, + "headerTrueBool": { + "target": BOOLEAN, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Boolean1") + ], + }, + "headerFalseBool": { + "target": BOOLEAN, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Boolean2") + ], + }, + "headerStringList": { + "target": STRING_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-StringList") + ], + }, + "headerStringSet": { + "target": STRING_SET, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-StringSet") + ], + }, + "headerIntegerList": { + "target": INTEGER_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-IntegerList") + ], + }, + "headerBooleanList": { + "target": BOOLEAN_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-BooleanList") + ], + }, + "headerTimestampList": { + "target": TIMESTAMP_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-TimestampList") + ], + }, + "headerEnum": { + "target": FOO_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Enum")], + }, + "headerEnumList": { + "target": FOO_ENUM_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-EnumList") + ], + }, + "headerIntegerEnum": { + "target": INTEGER_ENUM, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-IntegerEnum") + ], + }, + "headerIntegerEnumList": { + "target": INTEGER_ENUM_LIST, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-IntegerEnumList" + ) + ], + }, + }, +) + +INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#InputAndOutputWithHeadersOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#InputAndOutputWithHeadersIO", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "headerString": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-String") + ], + }, + "headerByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Byte")], + }, + "headerShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Short")], + }, + "headerInteger": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Integer") + ], + }, + "headerLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Long")], + }, + "headerFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Float")], + }, + "headerDouble": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Double") + ], + }, + "headerTrueBool": { + "target": BOOLEAN, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Boolean1") + ], + }, + "headerFalseBool": { + "target": BOOLEAN, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Boolean2") + ], + }, + "headerStringList": { + "target": STRING_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-StringList") + ], + }, + "headerStringSet": { + "target": STRING_SET, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-StringSet") + ], + }, + "headerIntegerList": { + "target": INTEGER_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-IntegerList") + ], + }, + "headerBooleanList": { + "target": BOOLEAN_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-BooleanList") + ], + }, + "headerTimestampList": { + "target": TIMESTAMP_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-TimestampList") + ], + }, + "headerEnum": { + "target": FOO_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Enum")], + }, + "headerEnumList": { + "target": FOO_ENUM_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-EnumList") + ], + }, + "headerIntegerEnum": { + "target": INTEGER_ENUM, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-IntegerEnum") + ], + }, + "headerIntegerEnumList": { + "target": INTEGER_ENUM_LIST, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-IntegerEnumList" + ) + ], + }, + }, +) + +INPUT_AND_OUTPUT_WITH_HEADERS = Schema( + id=ShapeID("aws.protocoltests.restjson#InputAndOutputWithHeaders"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithStringHeaders", + "documentation": "Tests requests with string header bindings", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "headers": MappingProxyType( + { + "X-String": "Hello", + "X-StringList": "a, b, c", + "X-StringSet": "a, b, c", + } + ), + "body": "", + "params": MappingProxyType( + { + "headerString": "Hello", + "headerStringList": ("a", "b", "c"), + "headerStringSet": ("a", "b", "c"), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithQuotedStringHeaders", + "documentation": "Tests requests with string list header bindings that require quoting", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "headers": MappingProxyType( + {"X-StringList": '"b,c", "\\"def\\"", a'} + ), + "body": "", + "params": MappingProxyType( + {"headerStringList": ("b,c", '"def"', "a")} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithNumericHeaders", + "documentation": "Tests requests with numeric header bindings", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "headers": MappingProxyType( + { + "X-Byte": "1", + "X-Short": "123", + "X-Integer": "123", + "X-Long": "123", + "X-Float": "1.1", + "X-Double": "1.1", + "X-IntegerList": "1, 2, 3", + } + ), + "body": "", + "params": MappingProxyType( + { + "headerByte": 1, + "headerShort": 123, + "headerInteger": 123, + "headerLong": 123, + "headerFloat": 1.1, + "headerDouble": 1.1, + "headerIntegerList": (1, 2, 3), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithBooleanHeaders", + "documentation": "Tests requests with boolean header bindings", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "headers": MappingProxyType( + { + "X-Boolean1": "true", + "X-Boolean2": "false", + "X-BooleanList": "true, false, true", + } + ), + "body": "", + "params": MappingProxyType( + { + "headerTrueBool": True, + "headerFalseBool": False, + "headerBooleanList": (True, False, True), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithTimestampHeaders", + "documentation": "Tests requests with timestamp header bindings", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "headers": MappingProxyType( + { + "X-TimestampList": "Mon, 16 Dec 2019 23:48:18 GMT, Mon, 16 Dec 2019 23:48:18 GMT" + } + ), + "body": "", + "params": MappingProxyType( + {"headerTimestampList": (1576540098, 1576540098)} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithEnumHeaders", + "documentation": "Tests requests with enum header bindings", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "headers": MappingProxyType( + {"X-Enum": "Foo", "X-EnumList": "Foo, Bar, Baz"} + ), + "body": "", + "params": MappingProxyType( + { + "headerEnum": "Foo", + "headerEnumList": ("Foo", "Bar", "Baz"), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithIntEnumHeaders", + "documentation": "Tests requests with intEnum header bindings", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "headers": MappingProxyType( + {"X-IntegerEnum": "1", "X-IntegerEnumList": "1, 2, 3"} + ), + "body": "", + "params": MappingProxyType( + {"headerIntegerEnum": 1, "headerIntegerEnumList": (1, 2, 3)} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNaNFloatHeaderInputs", + "documentation": "Supports handling NaN float header values.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": MappingProxyType( + {"X-Float": "NaN", "X-Double": "NaN"} + ), + "params": MappingProxyType( + {"headerFloat": "NaN", "headerDouble": "NaN"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsInfinityFloatHeaderInputs", + "documentation": "Supports handling Infinity float header values.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": MappingProxyType( + {"X-Float": "Infinity", "X-Double": "Infinity"} + ), + "params": MappingProxyType( + {"headerFloat": "Infinity", "headerDouble": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNegativeInfinityFloatHeaderInputs", + "documentation": "Supports handling -Infinity float header values.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/InputAndOutputWithHeaders", + "body": "", + "headers": MappingProxyType( + {"X-Float": "-Infinity", "X-Double": "-Infinity"} + ), + "params": MappingProxyType( + {"headerFloat": "-Infinity", "headerDouble": "-Infinity"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithStringHeaders", + "documentation": "Tests responses with string header bindings", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + { + "X-String": "Hello", + "X-StringList": "a, b, c", + "X-StringSet": "a, b, c", + } + ), + "params": MappingProxyType( + { + "headerString": "Hello", + "headerStringList": ("a", "b", "c"), + "headerStringSet": ("a", "b", "c"), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithQuotedStringHeaders", + "documentation": "Tests responses with string list header bindings that require quoting", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + {"X-StringList": '"b,c", "\\"def\\"", a'} + ), + "params": MappingProxyType( + {"headerStringList": ("b,c", '"def"', "a")} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithNumericHeaders", + "documentation": "Tests responses with numeric header bindings", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + { + "X-Byte": "1", + "X-Short": "123", + "X-Integer": "123", + "X-Long": "123", + "X-Float": "1.1", + "X-Double": "1.1", + "X-IntegerList": "1, 2, 3", + } + ), + "params": MappingProxyType( + { + "headerByte": 1, + "headerShort": 123, + "headerInteger": 123, + "headerLong": 123, + "headerFloat": 1.1, + "headerDouble": 1.1, + "headerIntegerList": (1, 2, 3), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithBooleanHeaders", + "documentation": "Tests responses with boolean header bindings", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + { + "X-Boolean1": "true", + "X-Boolean2": "false", + "X-BooleanList": "true, false, true", + } + ), + "params": MappingProxyType( + { + "headerTrueBool": True, + "headerFalseBool": False, + "headerBooleanList": (True, False, True), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithTimestampHeaders", + "documentation": "Tests responses with timestamp header bindings", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + { + "X-TimestampList": "Mon, 16 Dec 2019 23:48:18 GMT, Mon, 16 Dec 2019 23:48:18 GMT" + } + ), + "params": MappingProxyType( + {"headerTimestampList": (1576540098, 1576540098)} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithEnumHeaders", + "documentation": "Tests responses with enum header bindings", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + {"X-Enum": "Foo", "X-EnumList": "Foo, Bar, Baz"} + ), + "params": MappingProxyType( + { + "headerEnum": "Foo", + "headerEnumList": ("Foo", "Bar", "Baz"), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonInputAndOutputWithIntEnumHeaders", + "documentation": "Tests responses with intEnum header bindings", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + {"X-IntegerEnum": "1", "X-IntegerEnumList": "1, 2, 3"} + ), + "params": MappingProxyType( + {"headerIntegerEnum": 1, "headerIntegerEnumList": (1, 2, 3)} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNaNFloatHeaderOutputs", + "documentation": "Supports handling NaN float header values.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + {"X-Float": "NaN", "X-Double": "NaN"} + ), + "params": MappingProxyType( + {"headerFloat": "NaN", "headerDouble": "NaN"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsInfinityFloatHeaderOutputs", + "documentation": "Supports handling Infinity float header values.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + {"X-Float": "Infinity", "X-Double": "Infinity"} + ), + "params": MappingProxyType( + {"headerFloat": "Infinity", "headerDouble": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNegativeInfinityFloatHeaderOutputs", + "documentation": "Supports handling -Infinity float header values.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + {"X-Float": "-Infinity", "X-Double": "-Infinity"} + ), + "params": MappingProxyType( + {"headerFloat": "-Infinity", "headerDouble": "-Infinity"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/InputAndOutputWithHeaders", "method": "POST"} + ), + ), + ], +) + +INPUT_STREAM_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#InputStreamInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "stream": { + "target": EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +INPUT_STREAM_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#InputStreamOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +INPUT_STREAM = Schema( + id=ShapeID("aws.protocoltests.restjson#InputStream"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"method": "POST", "uri": "/InputStream"}), + ), + Trait.new( + id=ShapeID("smithy.test#eventStreamTests"), + value=( + MappingProxyType( + { + "id": "BooleanHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"booleanHeader": True} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgC4J9Ws", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "ByteHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + {"headers": MappingProxyType({"byteHeader": 1})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "byteHeader": MappingProxyType({"byte": 1}), + } + ), + "bytes": "AAAASQAAADlvxG1ZDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKYnl0ZUhlYWRlcgIBKFTmjg==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "ShortHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"shortHeader": 2} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "shortHeader": MappingProxyType( + {"short": 2} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMLc2hvcnRIZWFkZXIDAAL1ETsK", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "IntegerHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + {"headers": MappingProxyType({"intHeader": 3})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "intHeader": MappingProxyType( + {"integer": 3} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMJaW50SGVhZGVyBAAAAAPlyUrb", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "LongHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"longHeader": 4294967294} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "longHeader": MappingProxyType( + {"long": 4294967294} + ), + } + ), + "bytes": "AAAAUAAAAEAr7VEyDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKbG9uZ0hlYWRlcgUAAAAA/////udnd/I=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "BlobHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"blobHeader": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "blobHeader": MappingProxyType( + {"blob": "Zm9v"} + ), + } + ), + "bytes": "AAAATQAAAD2dKQ+ADTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKYmxvYkhlYWRlcgYAA2Zvb5sbbGM=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "StringHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"stringHeader": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "stringHeader": MappingProxyType( + {"string": "foo"} + ), + } + ), + "bytes": "AAAATwAAAD8J5z3MDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMMc3RyaW5nSGVhZGVyBwADZm9vxT+2MA==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "TimestampHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + { + "timestampHeader": "2024-10-31T14:15:14Z" + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "timestampHeader": MappingProxyType( + {"timestamp": "2024-10-31T14:15:14Z"} + ), + } + ), + "bytes": "AAAAVQAAAEWTZyrNDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMPdGltZXN0YW1wSGVhZGVyCAAAAZLi7jFQ6uV3Eg==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "MultipleHeaderInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + { + "booleanHeader": True, + "stringHeader": "foo", + "blobHeader": "bar", + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + "stringHeader": MappingProxyType( + {"string": "foo"} + ), + "blobHeader": MappingProxyType( + {"blob": "YmFy"} + ), + } + ), + "bytes": "AAAAbwAAAF+FlHOQDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgAMc3RyaW5nSGVhZGVyBwADZm9vCmJsb2JIZWFkZXIGAANiYXIDXbo7", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "StringPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "stringPayload": MappingProxyType( + {"payload": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "stringPayload"} + ), + ":content-type": MappingProxyType( + {"string": "text/plain"} + ), + } + ), + "body": "foo", + "bodyMediaType": "text/plain", + "bytes": "AAAAYAAAAE30fZUJDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcADXN0cmluZ1BheWxvYWQNOmNvbnRlbnQtdHlwZQcACnRleHQvcGxhaW5mb29G1ELr", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "BlobPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "blobPayload": MappingProxyType( + {"payload": "bar"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "blobPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/octet-stream"} + ), + } + ), + "body": "bar", + "bodyMediaType": "application/octet-stream", + "bytes": "AAAAbAAAAFkrV6x1DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAC2Jsb2JQYXlsb2FkDTpjb250ZW50LXR5cGUHABhhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1iYXJv5nGJ", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "StructurePayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "structurePayload": MappingProxyType( + { + "payload": MappingProxyType( + {"structureMember": "foo"} + ) + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "structurePayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"structureMember":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAfwAAAFacqFy2DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAEHN0cnVjdHVyZVBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257InN0cnVjdHVyZU1lbWJlciI6ImZvbyJ9rcIRVA==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "UnionPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "unionPayload": MappingProxyType( + { + "payload": MappingProxyType( + {"unionMember": "bar"} + ) + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "unionPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"unionMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdwAAAFKrtdNuDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcADHVuaW9uUGF5bG9hZA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbnsidW5pb25NZW1iZXIiOiJiYXIifcZDMD4=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "HeadersAndExplicitPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifTafKXs=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "HeadersAndImplicitPayloadInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndImplicitPayload": MappingProxyType( + {"header": "foo", "payload": "bar"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headersAndImplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"payload":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAjQAAAGxoUIY5DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRJbXBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJwYXlsb2FkIjoiYmFyIn15lZtT", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "ServerErrorInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + {"error": MappingProxyType({"message": "foo"})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "exception"} + ), + ":exception-type": MappingProxyType( + {"string": "error"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"message":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdAAAAFObEpkoDTptZXNzYWdlLXR5cGUHAAlleGNlcHRpb24POmV4Y2VwdGlvbi10eXBlBwAFZXJyb3INOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257Im1lc3NhZ2UiOiJmb28ifTua1S8=", + } + ), + ), + "expectation": MappingProxyType( + { + "failure": MappingProxyType( + {"errorId": "aws.protocoltests.restjson#ErrorEvent"} + ) + } + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "ClientErrorInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + {"error": MappingProxyType({"message": "foo"})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "exception"} + ), + ":exception-type": MappingProxyType( + {"string": "error"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"message":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdAAAAFObEpkoDTptZXNzYWdlLXR5cGUHAAlleGNlcHRpb24POmV4Y2VwdGlvbi10eXBlBwAFZXJyb3INOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257Im1lc3NhZ2UiOiJmb28ifTua1S8=", + } + ), + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "ServerUnexpectedErrorInput", + "documentation": "Servers must be able to handle structured, but unmodeled errors.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "error"} + ), + ":error-code": MappingProxyType( + {"string": "internal-error"} + ), + ":error-message": MappingProxyType( + {"string": "An unknown error occurred."} + ), + } + ), + "bytes": "AAAAbwAAAF+FlHOQDTptZXNzYWdlLXR5cGUHAAVlcnJvcgs6ZXJyb3ItY29kZQcADmludGVybmFsLWVycm9yDjplcnJvci1tZXNzYWdlBwAaQW4gdW5rbm93biBlcnJvciBvY2N1cnJlZC4kun0t", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "MissingMessageTypeInput", + "documentation": "Servers must reject events that don't contain a :message-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAfwAAAFacqFy2CzpldmVudC10eXBlBwAZaGVhZGVyc0FuZEV4cGxpY2l0UGF5bG9hZA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbgZoZWFkZXIHAANmb297InN0cnVjdHVyZU1lbWJlciI6ImJhciJ98LexJg==", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "MalformedMessageTypeInput", + "documentation": "Servers must reject events that contain a malformed :message-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"blob": "ZXZlbnQ="} + ), + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUGAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifVwdfzU=", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "MissingEventTypeInput", + "documentation": "Servers must reject message events that don't contain an :event-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAbQAAAER1MekcDTptZXNzYWdlLXR5cGUHAAVldmVudA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbgZoZWFkZXIHAANmb297InN0cnVjdHVyZU1lbWJlciI6ImJhciJ9riy0Gg==", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "MalformedEventTypeInput", + "documentation": "Servers must reject message events that contain a malformed :event-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + { + "blob": "aGVhZGVyc0FuZEV4cGxpY2l0UGF5bG9hZA==" + } + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQYAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifcP6KLk=", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + ), + ), + ], +) + +INPUT_STREAM_WITH_INITIAL_REQUEST_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#InputStreamWithInitialRequestInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "initialRequestMember": { + "target": STRING, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="initial-request-member" + ), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "stream": { + "target": EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +INPUT_STREAM_WITH_INITIAL_REQUEST_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#InputStreamWithInitialRequestOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +INPUT_STREAM_WITH_INITIAL_REQUEST = Schema( + id=ShapeID("aws.protocoltests.restjson#InputStreamWithInitialRequest"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/InputStreamWithInitialRequest"} + ), + ), + Trait.new( + id=ShapeID("smithy.test#eventStreamTests"), + value=( + MappingProxyType( + { + "id": "InitialRequestInput", + "protocol": "aws.protocols#restJson1", + "initialRequestParams": MappingProxyType( + {"initialRequestMember": "foo"} + ), + "initialRequest": MappingProxyType( + { + "method": "POST", + "uri": "/InputStreamWithInitialRequest", + "headers": MappingProxyType( + {"initial-request-member": "foo"} + ), + } + ), + "initialRequestShape": "smithy.test#InitialHttpRequest", + } + ), + MappingProxyType( + { + "id": "MissingRequiredInitialRequestInput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "request", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"booleanHeader": True} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgC4J9Ws", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "server", + } + ), + ), + ), + ], +) + +JSON_BLOBS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonBlobsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonBlobsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"data": {"target": BLOB}}, +) + +JSON_BLOBS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonBlobsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonBlobsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"data": {"target": BLOB}}, +) + +JSON_BLOBS = Schema( + id=ShapeID("aws.protocoltests.restjson#JsonBlobs"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonBlobs", + "documentation": "Blobs are base64 encoded", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonBlobs", + "body": '{\n "data": "dmFsdWU="\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"data": "value"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonBlobs", + "documentation": "Blobs are base64 encoded", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "data": "dmFsdWU="\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"data": "value"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/JsonBlobs", "method": "POST"}), + ), + ], +) + +FOO_ENUM_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnumMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": FOO_ENUM}}, +) + +FOO_ENUM_SET = Schema.collection( + id=ShapeID("aws.protocoltests.shared#FooEnumSet"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#uniqueItems"))], + members={"member": {"target": FOO_ENUM}}, +) + +JSON_ENUMS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonEnumsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonEnumsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "fooEnum1": {"target": FOO_ENUM}, + "fooEnum2": {"target": FOO_ENUM}, + "fooEnum3": {"target": FOO_ENUM}, + "fooEnumList": {"target": FOO_ENUM_LIST}, + "fooEnumSet": {"target": FOO_ENUM_SET}, + "fooEnumMap": {"target": FOO_ENUM_MAP}, + }, +) + +JSON_ENUMS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonEnumsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonEnumsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "fooEnum1": {"target": FOO_ENUM}, + "fooEnum2": {"target": FOO_ENUM}, + "fooEnum3": {"target": FOO_ENUM}, + "fooEnumList": {"target": FOO_ENUM_LIST}, + "fooEnumSet": {"target": FOO_ENUM_SET}, + "fooEnumMap": {"target": FOO_ENUM_MAP}, + }, +) + +JSON_ENUMS = Schema( + id=ShapeID("aws.protocoltests.restjson#JsonEnums"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonEnums", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonEnums", + "body": '{\n "fooEnum1": "Foo",\n "fooEnum2": "0",\n "fooEnum3": "1",\n "fooEnumList": [\n "Foo",\n "0"\n ],\n "fooEnumSet": [\n "Foo",\n "0"\n ],\n "fooEnumMap": {\n "hi": "Foo",\n "zero": "0"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": ("Foo", "0"), + "fooEnumSet": ("Foo", "0"), + "fooEnumMap": MappingProxyType( + {"hi": "Foo", "zero": "0"} + ), + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonEnums", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "fooEnum1": "Foo",\n "fooEnum2": "0",\n "fooEnum3": "1",\n "fooEnumList": [\n "Foo",\n "0"\n ],\n "fooEnumSet": [\n "Foo",\n "0"\n ],\n "fooEnumMap": {\n "hi": "Foo",\n "zero": "0"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "fooEnum1": "Foo", + "fooEnum2": "0", + "fooEnum3": "1", + "fooEnumList": ("Foo", "0"), + "fooEnumSet": ("Foo", "0"), + "fooEnumMap": MappingProxyType( + {"hi": "Foo", "zero": "0"} + ), + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/JsonEnums", "method": "PUT"}), + ), + ], +) + +JSON_HEADER_STRING = Schema( + id=ShapeID("aws.protocoltests.restjson#JsonHeaderString"), + shape_type=ShapeType.STRING, + traits=[Trait.new(id=ShapeID("smithy.api#mediaType"), value="application/json")], +) + +INTEGER_ENUM_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnumMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": INTEGER_ENUM}}, +) + +INTEGER_ENUM_SET = Schema.collection( + id=ShapeID("aws.protocoltests.shared#IntegerEnumSet"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#uniqueItems"))], + members={"member": {"target": INTEGER_ENUM}}, +) + +JSON_INT_ENUMS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonIntEnumsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonIntEnumsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "integerEnum1": {"target": INTEGER_ENUM}, + "integerEnum2": {"target": INTEGER_ENUM}, + "integerEnum3": {"target": INTEGER_ENUM}, + "integerEnumList": {"target": INTEGER_ENUM_LIST}, + "integerEnumSet": {"target": INTEGER_ENUM_SET}, + "integerEnumMap": {"target": INTEGER_ENUM_MAP}, + }, +) + +JSON_INT_ENUMS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonIntEnumsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonIntEnumsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "integerEnum1": {"target": INTEGER_ENUM}, + "integerEnum2": {"target": INTEGER_ENUM}, + "integerEnum3": {"target": INTEGER_ENUM}, + "integerEnumList": {"target": INTEGER_ENUM_LIST}, + "integerEnumSet": {"target": INTEGER_ENUM_SET}, + "integerEnumMap": {"target": INTEGER_ENUM_MAP}, + }, +) + +JSON_INT_ENUMS = Schema( + id=ShapeID("aws.protocoltests.restjson#JsonIntEnums"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonIntEnums", + "documentation": "Serializes intEnums as integers", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonIntEnums", + "body": '{\n "integerEnum1": 1,\n "integerEnum2": 2,\n "integerEnum3": 3,\n "integerEnumList": [\n 1,\n 2,\n 3\n ],\n "integerEnumSet": [\n 1,\n 2\n ],\n "integerEnumMap": {\n "abc": 1,\n "def": 2\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "integerEnum1": 1, + "integerEnum2": 2, + "integerEnum3": 3, + "integerEnumList": (1, 2, 3), + "integerEnumSet": (1, 2), + "integerEnumMap": MappingProxyType( + {"abc": 1, "def": 2} + ), + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonIntEnums", + "documentation": "Serializes intEnums as integers", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "integerEnum1": 1,\n "integerEnum2": 2,\n "integerEnum3": 3,\n "integerEnumList": [\n 1,\n 2,\n 3\n ],\n "integerEnumSet": [\n 1,\n 2\n ],\n "integerEnumMap": {\n "abc": 1,\n "def": 2\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "integerEnum1": 1, + "integerEnum2": 2, + "integerEnum3": 3, + "integerEnumList": (1, 2, 3), + "integerEnumSet": (1, 2), + "integerEnumMap": MappingProxyType( + {"abc": 1, "def": 2} + ), + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/JsonIntEnums", "method": "PUT"}), + ), + ], +) + +NESTED_STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#NestedStringList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING_LIST}}, +) + +STRUCTURE_LIST_MEMBER = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StructureListMember"), + members={ + "a": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#jsonName"), value="value")], + }, + "b": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#jsonName"), value="other")], + }, + }, +) + +STRUCTURE_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StructureList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRUCTURE_LIST_MEMBER}}, +) + +JSON_LISTS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonListsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonListsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "stringList": {"target": STRING_LIST}, + "stringSet": {"target": STRING_SET}, + "integerList": {"target": INTEGER_LIST}, + "booleanList": {"target": BOOLEAN_LIST}, + "timestampList": {"target": TIMESTAMP_LIST}, + "enumList": {"target": FOO_ENUM_LIST}, + "intEnumList": {"target": INTEGER_ENUM_LIST}, + "nestedStringList": {"target": NESTED_STRING_LIST}, + "structureList": { + "target": STRUCTURE_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#jsonName"), value="myStructureList") + ], + }, + }, +) + +JSON_LISTS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonListsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonListsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "stringList": {"target": STRING_LIST}, + "stringSet": {"target": STRING_SET}, + "integerList": {"target": INTEGER_LIST}, + "booleanList": {"target": BOOLEAN_LIST}, + "timestampList": {"target": TIMESTAMP_LIST}, + "enumList": {"target": FOO_ENUM_LIST}, + "intEnumList": {"target": INTEGER_ENUM_LIST}, + "nestedStringList": {"target": NESTED_STRING_LIST}, + "structureList": { + "target": STRUCTURE_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#jsonName"), value="myStructureList") + ], + }, + }, +) + +JSON_LISTS = Schema( + id=ShapeID("aws.protocoltests.restjson#JsonLists"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonLists", + "documentation": "Serializes JSON lists", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonLists", + "body": '{\n "stringList": [\n "foo",\n "bar"\n ],\n "stringSet": [\n "foo",\n "bar"\n ],\n "integerList": [\n 1,\n 2\n ],\n "booleanList": [\n true,\n false\n ],\n "timestampList": [\n 1398796238,\n 1398796238\n ],\n "enumList": [\n "Foo",\n "0"\n ],\n "intEnumList": [\n 1,\n 2\n ],\n "nestedStringList": [\n [\n "foo",\n "bar"\n ],\n [\n "baz",\n "qux"\n ]\n ],\n "myStructureList": [\n {\n "value": "1",\n "other": "2"\n },\n {\n "value": "3",\n "other": "4"\n }\n ]\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "stringList": ("foo", "bar"), + "stringSet": ("foo", "bar"), + "integerList": (1, 2), + "booleanList": (True, False), + "timestampList": (1398796238, 1398796238), + "enumList": ("Foo", "0"), + "intEnumList": (1, 2), + "nestedStringList": (("foo", "bar"), ("baz", "qux")), + "structureList": ( + MappingProxyType({"a": "1", "b": "2"}), + MappingProxyType({"a": "3", "b": "4"}), + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonListsEmpty", + "documentation": "Serializes empty JSON lists", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonLists", + "body": '{\n "stringList": []\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"stringList": ()}), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonLists", + "documentation": "Serializes JSON lists", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "stringList": [\n "foo",\n "bar"\n ],\n "stringSet": [\n "foo",\n "bar"\n ],\n "integerList": [\n 1,\n 2\n ],\n "booleanList": [\n true,\n false\n ],\n "timestampList": [\n 1398796238,\n 1398796238\n ],\n "enumList": [\n "Foo",\n "0"\n ],\n "intEnumList": [\n 1,\n 2\n ],\n "nestedStringList": [\n [\n "foo",\n "bar"\n ],\n [\n "baz",\n "qux"\n ]\n ],\n "myStructureList": [\n {\n "value": "1",\n "other": "2"\n },\n {\n "value": "3",\n "other": "4"\n }\n ]\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "stringList": ("foo", "bar"), + "stringSet": ("foo", "bar"), + "integerList": (1, 2), + "booleanList": (True, False), + "timestampList": (1398796238, 1398796238), + "enumList": ("Foo", "0"), + "intEnumList": (1, 2), + "nestedStringList": (("foo", "bar"), ("baz", "qux")), + "structureList": ( + MappingProxyType({"a": "1", "b": "2"}), + MappingProxyType({"a": "3", "b": "4"}), + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonListsEmpty", + "documentation": "Serializes empty JSON lists", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "stringList": []\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"stringList": ()}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/JsonLists", "method": "PUT"}), + ), + ], +) + +JSON_MAPS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonMapsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonMapsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "denseStructMap": {"target": DENSE_STRUCT_MAP}, + "denseNumberMap": {"target": DENSE_NUMBER_MAP}, + "denseBooleanMap": {"target": DENSE_BOOLEAN_MAP}, + "denseStringMap": {"target": DENSE_STRING_MAP}, + "denseSetMap": {"target": DENSE_SET_MAP}, + }, +) + +JSON_MAPS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonMapsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonMapsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "denseStructMap": {"target": DENSE_STRUCT_MAP}, + "denseNumberMap": {"target": DENSE_NUMBER_MAP}, + "denseBooleanMap": {"target": DENSE_BOOLEAN_MAP}, + "denseStringMap": {"target": DENSE_STRING_MAP}, + "denseSetMap": {"target": DENSE_SET_MAP}, + }, +) + +JSON_MAPS = Schema( + id=ShapeID("aws.protocoltests.restjson#JsonMaps"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonMaps", + "documentation": "Serializes JSON maps", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonMaps", + "body": '{\n "denseStructMap": {\n "foo": {\n "hi": "there"\n },\n "baz": {\n "hi": "bye"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "denseStructMap": MappingProxyType( + { + "foo": MappingProxyType({"hi": "there"}), + "baz": MappingProxyType({"hi": "bye"}), + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializesZeroValuesInMaps", + "documentation": "Ensure that 0 and false are sent over the wire in all maps and lists", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonMaps", + "body": '{\n "denseNumberMap": {\n "x": 0\n },\n "denseBooleanMap": {\n "x": false\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "denseNumberMap": MappingProxyType({"x": 0}), + "denseBooleanMap": MappingProxyType({"x": False}), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializesDenseSetMap", + "documentation": "A request that contains a dense map of sets.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonMaps", + "body": '{\n "denseSetMap": {\n "x": [],\n "y": ["a", "b"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "denseSetMap": MappingProxyType( + {"x": (), "y": ("a", "b")} + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonMaps", + "documentation": "Deserializes JSON maps", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "denseStructMap": {\n "foo": {\n "hi": "there"\n },\n "baz": {\n "hi": "bye"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "denseStructMap": MappingProxyType( + { + "foo": MappingProxyType({"hi": "there"}), + "baz": MappingProxyType({"hi": "bye"}), + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializesZeroValuesInMaps", + "documentation": "Ensure that 0 and false are sent over the wire in all maps and lists", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "denseNumberMap": {\n "x": 0\n },\n "denseBooleanMap": {\n "x": false\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "denseNumberMap": MappingProxyType({"x": 0}), + "denseBooleanMap": MappingProxyType({"x": False}), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializesDenseSetMap", + "documentation": "A response that contains a dense map of sets.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "denseSetMap": {\n "x": [],\n "y": ["a", "b"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "denseSetMap": MappingProxyType( + {"x": (), "y": ("a", "b")} + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/JsonMaps", "method": "POST"}), + ), + ], +) + +JSON_TIMESTAMPS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonTimestampsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonTimestampsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "normal": {"target": TIMESTAMP}, + "dateTime": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time") + ], + }, + "dateTimeOnTarget": {"target": DATE_TIME}, + "epochSeconds": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ) + ], + }, + "epochSecondsOnTarget": {"target": EPOCH_SECONDS}, + "httpDate": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date") + ], + }, + "httpDateOnTarget": {"target": HTTP_DATE}, + }, +) + +JSON_TIMESTAMPS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonTimestampsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#JsonTimestampsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "normal": {"target": TIMESTAMP}, + "dateTime": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time") + ], + }, + "dateTimeOnTarget": {"target": DATE_TIME}, + "epochSeconds": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ) + ], + }, + "epochSecondsOnTarget": {"target": EPOCH_SECONDS}, + "httpDate": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date") + ], + }, + "httpDateOnTarget": {"target": HTTP_DATE}, + }, +) + +JSON_TIMESTAMPS = Schema( + id=ShapeID("aws.protocoltests.restjson#JsonTimestamps"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonTimestamps", + "documentation": "Tests how normal timestamps are serialized", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonTimestamps", + "body": '{\n "normal": 1398796238\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"normal": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithDateTimeFormat", + "documentation": "Ensures that the timestampFormat of date-time works like normal timestamps", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonTimestamps", + "body": '{\n "dateTime": "2014-04-29T18:30:38Z"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"dateTime": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithDateTimeOnTargetFormat", + "documentation": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonTimestamps", + "body": '{\n "dateTimeOnTarget": "2014-04-29T18:30:38Z"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"dateTimeOnTarget": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithEpochSecondsFormat", + "documentation": "Ensures that the timestampFormat of epoch-seconds works", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonTimestamps", + "body": '{\n "epochSeconds": 1398796238\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"epochSeconds": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithEpochSecondsOnTargetFormat", + "documentation": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonTimestamps", + "body": '{\n "epochSecondsOnTarget": 1398796238\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"epochSecondsOnTarget": 1398796238} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithHttpDateFormat", + "documentation": "Ensures that the timestampFormat of http-date works", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonTimestamps", + "body": '{\n "httpDate": "Tue, 29 Apr 2014 18:30:38 GMT"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"httpDate": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithHttpDateOnTargetFormat", + "documentation": "Ensures that the timestampFormat of http-date on the target shape works", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/JsonTimestamps", + "body": '{\n "httpDateOnTarget": "Tue, 29 Apr 2014 18:30:38 GMT"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"httpDateOnTarget": 1398796238}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonJsonTimestamps", + "documentation": "Tests how normal timestamps are serialized", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "normal": 1398796238\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"normal": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithDateTimeFormat", + "documentation": "Ensures that the timestampFormat of date-time works like normal timestamps", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "dateTime": "2014-04-29T18:30:38Z"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"dateTime": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithDateTimeOnTargetFormat", + "documentation": "Ensures that the timestampFormat of date-time on the target shape works like normal timestamps", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "dateTimeOnTarget": "2014-04-29T18:30:38Z"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"dateTimeOnTarget": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithEpochSecondsFormat", + "documentation": "Ensures that the timestampFormat of epoch-seconds works", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "epochSeconds": 1398796238\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"epochSeconds": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithEpochSecondsOnTargetFormat", + "documentation": "Ensures that the timestampFormat of epoch-seconds on the target shape works", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "epochSecondsOnTarget": 1398796238\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"epochSecondsOnTarget": 1398796238} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithHttpDateFormat", + "documentation": "Ensures that the timestampFormat of http-date works", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "httpDate": "Tue, 29 Apr 2014 18:30:38 GMT"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"httpDate": 1398796238}), + } + ), + MappingProxyType( + { + "id": "RestJsonJsonTimestampsWithHttpDateOnTargetFormat", + "documentation": "Ensures that the timestampFormat of http-date on the target shape works", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "httpDateOnTarget": "Tue, 29 Apr 2014 18:30:38 GMT"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"httpDateOnTarget": 1398796238}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/JsonTimestamps", "method": "POST"}), + ), + ], +) + +RENAMED_GREETING = Schema.collection( + id=ShapeID("aws.protocoltests.restjson.nested#GreetingStruct"), + members={"salutation": {"target": STRING}}, +) + +NESTED_UNION = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NestedUnion"), + shape_type=ShapeType.UNION, + members={"stringValue": {"target": STRING}}, +) + +MY_UNION = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MyUnion"), + shape_type=ShapeType.UNION, + members={ + "stringValue": {"target": STRING}, + "booleanValue": {"target": BOOLEAN}, + "numberValue": {"target": INTEGER}, + "blobValue": {"target": BLOB}, + "timestampValue": {"target": TIMESTAMP}, + "enumValue": {"target": FOO_ENUM}, + "listValue": {"target": STRING_LIST}, + "mapValue": {"target": STRING_MAP}, + "structureValue": {"target": GREETING_STRUCT}, + "renamedStructureValue": {"target": RENAMED_GREETING}, + "unionValue": {"target": NESTED_UNION}, + }, +) + +JSON_UNIONS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonUnionsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#UnionInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"contents": {"target": MY_UNION}}, +) + +JSON_UNIONS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#JsonUnionsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#UnionInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"contents": {"target": MY_UNION}}, +) + +JSON_UNIONS = Schema( + id=ShapeID("aws.protocoltests.restjson#JsonUnions"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonSerializeStringUnionValue", + "documentation": "Serializes a string union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "stringValue": "foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"stringValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeBooleanUnionValue", + "documentation": "Serializes a boolean union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "booleanValue": true\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"booleanValue": True})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeNumberUnionValue", + "documentation": "Serializes a number union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "numberValue": 1\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"numberValue": 1})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeBlobUnionValue", + "documentation": "Serializes a blob union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "blobValue": "Zm9v"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"blobValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeTimestampUnionValue", + "documentation": "Serializes a timestamp union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "timestampValue": 1398796238\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"timestampValue": 1398796238} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeEnumUnionValue", + "documentation": "Serializes an enum union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "enumValue": "Foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"enumValue": "Foo"})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeListUnionValue", + "documentation": "Serializes a list union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"listValue": ("foo", "bar")} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeMapUnionValue", + "documentation": "Serializes a map union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "mapValue": MappingProxyType( + {"foo": "bar", "spam": "eggs"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeStructureUnionValue", + "documentation": "Serializes a structure union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeRenamedStructureUnionValue", + "documentation": "Serializes a renamed structure union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "renamedStructureValue": {\n "salutation": "hello!"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "renamedStructureValue": MappingProxyType( + {"salutation": "hello!"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializeNestedUnionValue", + "documentation": "Serializes a nested union value", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/JsonUnions", + "body": '{\n "contents": {\n "unionValue": {\n "stringValue": "foo"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "unionValue": MappingProxyType( + {"stringValue": "foo"} + ) + } + ) + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonDeserializeStringUnionValue", + "documentation": "Deserializes a string union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "stringValue": "foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"stringValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeBooleanUnionValue", + "documentation": "Deserializes a boolean union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "booleanValue": true\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"booleanValue": True})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeNumberUnionValue", + "documentation": "Deserializes a number union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "numberValue": 1\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"numberValue": 1})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeBlobUnionValue", + "documentation": "Deserializes a blob union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "blobValue": "Zm9v"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"blobValue": "foo"})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeTimestampUnionValue", + "documentation": "Deserializes a timestamp union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "timestampValue": 1398796238\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"timestampValue": 1398796238} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeEnumUnionValue", + "documentation": "Deserializes an enum union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "enumValue": "Foo"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"contents": MappingProxyType({"enumValue": "Foo"})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeListUnionValue", + "documentation": "Deserializes a list union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + {"listValue": ("foo", "bar")} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeMapUnionValue", + "documentation": "Deserializes a map union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "mapValue": MappingProxyType( + {"foo": "bar", "spam": "eggs"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeStructureUnionValue", + "documentation": "Deserializes a structure union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeNestedUnionValue", + "documentation": "Deserializes a nested union value", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "unionValue": {\n "stringValue": "foo"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "unionValue": MappingProxyType( + {"stringValue": "foo"} + ) + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializeIgnoreType", + "appliesTo": "client", + "documentation": "Ignores an unrecognized __type property", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "contents": {\n "__type": "aws.protocoltests.json10#MyUnion",\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "contents": MappingProxyType( + { + "structureValue": MappingProxyType( + {"hi": "hello"} + ) + } + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/JsonUnions", "method": "PUT"}), + ), + ], +) + +JSON_VALUE = Schema( + id=ShapeID("aws.protocoltests.restjson#JsonValue"), + shape_type=ShapeType.STRING, + traits=[Trait.new(id=ShapeID("smithy.api#mediaType"), value="application/json")], +) + +MALFORMED_ACCEPT_WITH_BODY_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedAcceptWithBodyInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +MALFORMED_ACCEPT_WITH_BODY_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedAcceptWithBodyOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.shared#GreetingStruct", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"hi": {"target": STRING}}, +) + +MALFORMED_ACCEPT_WITH_BODY = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedAcceptWithBody"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonWithBodyExpectsApplicationJsonAccept", + "documentation": "When there is modeled output, the accept must be application/json", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedAcceptWithBody", + "headers": MappingProxyType( + {"accept": "application/hal+json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 406, + "headers": MappingProxyType( + {"x-amzn-errortype": "NotAcceptableException"} + ), + } + ), + "tags": ("accept",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/MalformedAcceptWithBody"} + ), + ), + ], +) + +MALFORMED_ACCEPT_WITH_GENERIC_STRING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedAcceptWithGenericStringInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +MALFORMED_ACCEPT_WITH_GENERIC_STRING_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedAcceptWithGenericStringOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "payload": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +MALFORMED_ACCEPT_WITH_GENERIC_STRING = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedAcceptWithGenericString"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonWithPayloadExpectsImpliedAccept", + "documentation": "When there is a payload without a mediaType trait, the accept must match the\nimplied content type of the shape.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedAcceptWithGenericString", + "headers": MappingProxyType( + {"accept": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 406, + "headers": MappingProxyType( + {"x-amzn-errortype": "NotAcceptableException"} + ), + } + ), + "tags": ("accept",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/MalformedAcceptWithGenericString"} + ), + ), + ], +) + +MALFORMED_ACCEPT_WITH_PAYLOAD_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedAcceptWithPayloadInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +JPEG_BLOB = Schema( + id=ShapeID("aws.protocoltests.shared#JpegBlob"), + shape_type=ShapeType.BLOB, + traits=[Trait.new(id=ShapeID("smithy.api#mediaType"), value="image/jpeg")], +) + +MALFORMED_ACCEPT_WITH_PAYLOAD_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedAcceptWithPayloadOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "payload": { + "target": JPEG_BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +MALFORMED_ACCEPT_WITH_PAYLOAD = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedAcceptWithPayload"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonWithPayloadExpectsModeledAccept", + "documentation": "When there is a payload with a mediaType trait, the accept must match.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedAcceptWithPayload", + "headers": MappingProxyType( + {"accept": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 406, + "headers": MappingProxyType( + {"x-amzn-errortype": "NotAcceptableException"} + ), + } + ), + "tags": ("accept",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/MalformedAcceptWithPayload"} + ), + ), + ], +) + +MALFORMED_BLOB_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedBlobInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"blob": {"target": BLOB}}, +) + +MALFORMED_BLOB_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedBlobOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_BLOB = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedBlob"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyMalformedBlobInvalidBase64", + "documentation": "When a blob member is not properly base64 encoded, or not encoded at\nall, the response should be a 400 SerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedBlob", + "body": '{ "blob" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "blob", + '"xyz"', + '"YmxvYg="', + "[98, 108, 11, 98]", + '["b", "l","o","b"]', + "981081198", + "true", + "[][]", + "-_==", + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/MalformedBlob", "method": "POST"}), + ), + ], +) + +MALFORMED_BOOLEAN_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedBooleanInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "booleanInBody": {"target": BOOLEAN}, + "booleanInPath": { + "target": BOOLEAN, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "booleanInQuery": { + "target": BOOLEAN, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="booleanInQuery") + ], + }, + "booleanInHeader": { + "target": BOOLEAN, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="booleanInHeader") + ], + }, + }, +) + +MALFORMED_BOOLEAN_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedBooleanOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_BOOLEAN = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedBoolean"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyBooleanStringCoercion", + "documentation": "Attempted string coercion should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedBoolean/true", + "body": '{ "booleanInBody" : $value:S }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "True", + "TRUE", + "y", + "Y", + "yes", + "Yes", + "YES", + "1", + "on", + "On", + "ON", + "false", + "False", + "FALSE", + "n", + "N", + "no", + "No", + "NO", + "0", + "off", + "Off", + "OFF", + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyBooleanBadLiteral", + "documentation": "YAML-style alternate boolean literals should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedBoolean/true", + "body": '{ "booleanInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "True", + "TRUE", + "y", + "Y", + "yes", + "Yes", + "YES", + "1", + "on", + "On", + "ON", + "False", + "FALSE", + "n", + "N", + "no", + "No", + "NO", + "0", + "off", + "Off", + "OFF", + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonPathBooleanStringCoercion", + "documentation": "Attempted string coercion should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedBoolean/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "True", + "TRUE", + "y", + "Y", + "yes", + "Yes", + "YES", + "1", + "on", + "On", + "ON", + "False", + "FALSE", + "n", + "N", + "no", + "No", + "NO", + "0", + "off", + "Off", + "OFF", + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryBooleanStringCoercion", + "documentation": "Attempted string coercion should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedBoolean/true", + "queryParams": ("booleanInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "True", + "TRUE", + "y", + "Y", + "yes", + "Yes", + "YES", + "1", + "on", + "On", + "ON", + "False", + "FALSE", + "n", + "N", + "no", + "No", + "NO", + "0", + "off", + "Off", + "OFF", + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderBooleanStringCoercion", + "documentation": "Attempted string coercion should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedBoolean/true", + "headers": MappingProxyType( + {"booleanInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "True", + "TRUE", + "y", + "Y", + "yes", + "Yes", + "YES", + "1", + "on", + "On", + "ON", + "False", + "FALSE", + "n", + "N", + "no", + "No", + "NO", + "0", + "off", + "Off", + "OFF", + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedBoolean/{booleanInPath}", "method": "POST"} + ), + ), + ], +) + +MALFORMED_BYTE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedByteInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "byteInBody": {"target": BYTE}, + "byteInPath": { + "target": BYTE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "byteInQuery": { + "target": BYTE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="byteInQuery") + ], + }, + "byteInHeader": { + "target": BYTE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="byteInHeader") + ], + }, + }, +) + +MALFORMED_BYTE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedByteOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_BYTE = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedByte"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyByteUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedByte/1", + "body": '{ "byteInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "256", + "-256", + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathByteUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedByte/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "256", + "-256", + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryByteUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedByte/1", + "queryParams": ("byteInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "256", + "-256", + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderByteUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedByte/1", + "headers": MappingProxyType( + {"byteInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "256", + "-256", + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyByteMalformedValueRejected", + "documentation": "Malformed values in the body should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedByte/1", + "body": '{ "byteInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + '"123"', + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + '"Infinity"', + "-Infinity", + '"-Infinity"', + "NaN", + '"NaN"', + ), + "tag": ( + "string_coercion", + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "string_inf", + "negative_inf", + "string_negative_inf", + "nan", + "string_nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathByteMalformedValueRejected", + "documentation": "Malformed values in the path should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedByte/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryByteMalformedValueRejected", + "documentation": "Malformed values in query parameters should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedByte/1", + "queryParams": ("byteInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderByteMalformedValueRejected", + "documentation": "Malformed values in headers should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedByte/1", + "headers": MappingProxyType( + {"byteInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedByte/{byteInPath}", "method": "POST"} + ), + ), + ], +) + +MALFORMED_CONTENT_TYPE_WITH_BODY_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithBodyInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.shared#GreetingStruct", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"hi": {"target": STRING}}, +) + +MALFORMED_CONTENT_TYPE_WITH_BODY_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithBodyOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_CONTENT_TYPE_WITH_BODY = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithBody"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonWithBodyExpectsApplicationJsonContentType", + "documentation": "When there is modeled input, the content type must be application/json", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedContentTypeWithBody", + "body": "{}", + "headers": MappingProxyType( + {"content-type": "application/hal+json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 415, + "headers": MappingProxyType( + { + "x-amzn-errortype": "UnsupportedMediaTypeException" + } + ), + } + ), + "tags": ("content-type",), + } + ), + MappingProxyType( + { + "id": "RestJsonWithBodyExpectsApplicationJsonContentTypeNoHeaders", + "documentation": "When there is modeled input, the content type must be application/json", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedContentTypeWithBody", + "body": "{}", + } + ), + "response": MappingProxyType( + { + "code": 415, + "headers": MappingProxyType( + { + "x-amzn-errortype": "UnsupportedMediaTypeException" + } + ), + } + ), + "tags": ("content-type",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/MalformedContentTypeWithBody"} + ), + ), + ], +) + +MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithGenericStringInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "payload": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_OUTPUT = Schema.collection( + id=ShapeID( + "aws.protocoltests.restjson#MalformedContentTypeWithGenericStringOutput" + ), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithGenericString"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/MalformedContentTypeWithGenericString"} + ), + ), + ], +) + +MALFORMED_CONTENT_TYPE_WITHOUT_BODY_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithoutBodyInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +MALFORMED_CONTENT_TYPE_WITHOUT_BODY_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithoutBodyOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_CONTENT_TYPE_WITHOUT_BODY = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithoutBody"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonWithoutBodyExpectsEmptyContentType", + "documentation": "When there is no modeled input, content type must not be set and the body must be empty.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedContentTypeWithoutBody", + "body": "{}", + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 415, + "headers": MappingProxyType( + { + "x-amzn-errortype": "UnsupportedMediaTypeException" + } + ), + } + ), + "tags": ("content-type",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/MalformedContentTypeWithoutBody"} + ), + ), + ], +) + +MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_INPUT = Schema.collection( + id=ShapeID( + "aws.protocoltests.restjson#MalformedContentTypeWithoutBodyEmptyInputInput" + ), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "header": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="header")], + } + }, +) + +MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_OUTPUT = Schema.collection( + id=ShapeID( + "aws.protocoltests.restjson#MalformedContentTypeWithoutBodyEmptyInputOutput" + ), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithoutBodyEmptyInput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonWithoutBodyEmptyInputExpectsEmptyContentType", + "documentation": "When there is no modeled body input, content type must not be set and the body must be empty.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedContentTypeWithoutBodyEmptyInput", + "body": "{}", + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 415, + "headers": MappingProxyType( + { + "x-amzn-errortype": "UnsupportedMediaTypeException" + } + ), + } + ), + "tags": ("content-type",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/MalformedContentTypeWithoutBodyEmptyInput"} + ), + ), + ], +) + +MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithPayloadInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "payload": { + "target": JPEG_BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithPayloadOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_CONTENT_TYPE_WITH_PAYLOAD = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedContentTypeWithPayload"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonWithPayloadExpectsModeledContentType", + "documentation": "When there is a payload with a mediaType trait, the content type must match.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedContentTypeWithPayload", + "body": "{}", + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 415, + "headers": MappingProxyType( + { + "x-amzn-errortype": "UnsupportedMediaTypeException" + } + ), + } + ), + "tags": ("content-type",), + } + ), + MappingProxyType( + { + "id": "RestJsonWithPayloadExpectsImpliedContentType", + "documentation": "When there is a payload without a mediaType trait, the content type must match the\nimplied content type of the shape.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedContentTypeWithPayload", + "body": "{}", + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 415, + "headers": MappingProxyType( + { + "x-amzn-errortype": "UnsupportedMediaTypeException" + } + ), + } + ), + "tags": ("content-type",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/MalformedContentTypeWithPayload"} + ), + ), + ], +) + +MALFORMED_DOUBLE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedDoubleInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "doubleInBody": {"target": DOUBLE}, + "doubleInPath": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "doubleInQuery": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="doubleInQuery") + ], + }, + "doubleInHeader": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="doubleInHeader") + ], + }, + }, +) + +MALFORMED_DOUBLE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedDoubleOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_DOUBLE = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedDouble"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyDoubleMalformedValueRejected", + "documentation": "Malformed values in the body should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedDouble/1", + "body": '{ "doubleInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + '"123"', + "true", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "string_coercion", + "boolean_coercion", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathDoubleMalformedValueRejected", + "documentation": "Malformed values in the path should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedDouble/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ("true", "2ABC", "0x42"), + "tag": ("boolean_coercion", "trailing_chars", "hex"), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryDoubleMalformedValueRejected", + "documentation": "Malformed values in query parameters should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedDouble/1", + "queryParams": ("doubleInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ("true", "2ABC", "0x42"), + "tag": ("boolean_coercion", "trailing_chars", "hex"), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderDoubleMalformedValueRejected", + "documentation": "Malformed values in headers should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedDouble/1", + "headers": MappingProxyType( + {"doubleInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ("true", "2ABC", "0x42"), + "tag": ("boolean_coercion", "trailing_chars", "hex"), + } + ), + "tags": ("$tag:L",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedDouble/{doubleInPath}", "method": "POST"} + ), + ), + ], +) + +MALFORMED_FLOAT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedFloatInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "floatInBody": {"target": FLOAT}, + "floatInPath": { + "target": FLOAT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "floatInQuery": { + "target": FLOAT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="floatInQuery") + ], + }, + "floatInHeader": { + "target": FLOAT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="floatInHeader") + ], + }, + }, +) + +MALFORMED_FLOAT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedFloatOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_FLOAT = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedFloat"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyFloatMalformedValueRejected", + "documentation": "Malformed values in the body should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedFloat/1", + "body": '{ "floatInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + '"123"', + "true", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "string_coercion", + "boolean_coercion", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathFloatMalformedValueRejected", + "documentation": "Malformed values in the path should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedFloat/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ("true", "2ABC", "0x42"), + "tag": ("boolean_coercion", "trailing_chars", "hex"), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryFloatMalformedValueRejected", + "documentation": "Malformed values in query parameters should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedFloat/1", + "queryParams": ("floatInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ("true", "2ABC", "0x42"), + "tag": ("boolean_coercion", "trailing_chars", "hex"), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderFloatMalformedValueRejected", + "documentation": "Malformed values in headers should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedFloat/1", + "headers": MappingProxyType( + {"floatInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ("true", "2ABC", "0x42"), + "tag": ("boolean_coercion", "trailing_chars", "hex"), + } + ), + "tags": ("$tag:L",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedFloat/{floatInPath}", "method": "POST"} + ), + ), + ], +) + +MALFORMED_INTEGER_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedIntegerInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "integerInBody": {"target": INTEGER}, + "integerInPath": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "integerInQuery": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="integerInQuery") + ], + }, + "integerInHeader": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="integerInHeader") + ], + }, + }, +) + +MALFORMED_INTEGER_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedIntegerOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_INTEGER = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedInteger"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyIntegerUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedInteger/1", + "body": '{ "integerInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathIntegerUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedInteger/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryIntegerUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedInteger/1", + "queryParams": ("integerInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderIntegerUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedInteger/1", + "headers": MappingProxyType( + {"integerInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyIntegerMalformedValueRejected", + "documentation": "Malformed values in the body should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedInteger/1", + "body": '{ "integerInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + '"123"', + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + '"Infinity"', + "-Infinity", + '"-Infinity"', + "NaN", + '"NaN"', + ), + "tag": ( + "string_coercion", + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "string_inf", + "negative_inf", + "string_negative_inf", + "nan", + "string_nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathIntegerMalformedValueRejected", + "documentation": "Malformed values in the path should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedInteger/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryIntegerMalformedValueRejected", + "documentation": "Malformed values in query parameters should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedInteger/1", + "queryParams": ("integerInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderIntegerMalformedValueRejected", + "documentation": "Malformed values in headers should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedInteger/1", + "headers": MappingProxyType( + {"integerInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedInteger/{integerInPath}", "method": "POST"} + ), + ), + ], +) + +SIMPLE_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SimpleList"), + shape_type=ShapeType.LIST, + members={"member": {"target": STRING}}, +) + +MALFORMED_LIST_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedListInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"bodyList": {"target": SIMPLE_LIST}}, +) + +MALFORMED_LIST_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedListOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_LIST = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedList"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyMalformedListNullItem", + "documentation": "When a dense list contains null, the response should be a 400\nSerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedList", + "body": '{ "bodyList" : ["a", null, "b", "c"] }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyMalformedListUnclosed", + "documentation": "When a list does not have a closing bracket, the response should be\na 400 SerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedList", + "body": '{ "bodyList" : ["a", "b", "c" }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/MalformedList", "method": "POST"}), + ), + ], +) + +MALFORMED_LONG_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedLongInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "longInBody": {"target": LONG}, + "longInPath": { + "target": LONG, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "longInQuery": { + "target": LONG, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="longInQuery") + ], + }, + "longInHeader": { + "target": LONG, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="longInHeader") + ], + }, + }, +) + +MALFORMED_LONG_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedLongOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_LONG = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedLong"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyLongUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedLong/1", + "body": '{ "longInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "-184467440737095500000", + "184467440737095500000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathLongUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedLong/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "-184467440737095500000", + "184467440737095500000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryLongUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedLong/1", + "queryParams": ("longInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "-184467440737095500000", + "184467440737095500000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderLongUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedLong/1", + "headers": MappingProxyType( + {"longInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "-184467440737095500000", + "184467440737095500000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyLongMalformedValueRejected", + "documentation": "Malformed values in the body should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedLong/1", + "body": '{ "longInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + '"123"', + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + '"Infinity"', + "-Infinity", + '"-Infinity"', + "NaN", + '"NaN"', + ), + "tag": ( + "string_coercion", + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "string_inf", + "negative_inf", + "string_negative_inf", + "nan", + "string_nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathLongMalformedValueRejected", + "documentation": "Malformed values in the path should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedLong/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryLongMalformedValueRejected", + "documentation": "Malformed values in query parameters should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedLong/1", + "queryParams": ("longInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderLongMalformedValueRejected", + "documentation": "Malformed values in headers should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedLong/1", + "headers": MappingProxyType( + {"longInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedLong/{longInPath}", "method": "POST"} + ), + ), + ], +) + +SIMPLE_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SimpleMap"), + shape_type=ShapeType.MAP, + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +MALFORMED_MAP_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedMapInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"bodyMap": {"target": SIMPLE_MAP}}, +) + +MALFORMED_MAP_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedMapOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_MAP = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedMap"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyMalformedMapNullKey", + "documentation": "When a map contains a null key, the response should be a 400\nSerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedMap", + "body": '{ "bodyMap" : { null: "abc" } }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyMalformedMapNullValue", + "documentation": "When a dense map contains a null value, the response should be a 400\nSerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedMap", + "body": '{ "bodyMap" : { "abc": null } }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/MalformedMap", "method": "POST"}), + ), + ], +) + +MALFORMED_REQUEST_BODY_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedRequestBodyInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"int": {"target": INTEGER}, "float": {"target": FLOAT}}, +) + +MALFORMED_REQUEST_BODY_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedRequestBodyOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_REQUEST_BODY = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedRequestBody"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonInvalidJsonBody", + "documentation": "When the request body is not valid JSON, the response should be a 400\nSerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedRequestBody", + "body": "$value:L", + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "{[", + '{ "int": 10 }abc', + 'abc{ "int": 10 }', + '{\n "int": 10 // the integer should be 10\n}', + '{\n "int": 10 /* the integer should be 10 */\n}', + '{"int" :\f10}', + "{'int': 10}", + '{"int": 10,}', + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonTechnicallyValidJsonBody", + "documentation": "When the request body is technically valid, but cannot map to a Smithy structure,\nthe response should be a 400 SerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedRequestBody", + "body": "$value:L", + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ('[{ "int": 10}]', "10", "null")} + ), + "tags": ("technically_valid_json_body",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/MalformedRequestBody", "method": "POST"}), + ), + ], +) + +MALFORMED_SHORT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedShortInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "shortInBody": {"target": SHORT}, + "shortInPath": { + "target": SHORT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + }, + "shortInQuery": { + "target": SHORT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="shortInQuery") + ], + }, + "shortInHeader": { + "target": SHORT, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="shortInHeader") + ], + }, + }, +) + +MALFORMED_SHORT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedShortOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_SHORT = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedShort"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyShortUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedShort/1", + "body": '{ "shortInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "40000", + "-40000", + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathShortUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedShort/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "40000", + "-40000", + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryShortUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedShort/1", + "queryParams": ("shortInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "40000", + "-40000", + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderShortUnderflowOverflow", + "documentation": "Underflow or overflow should result in SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedShort/1", + "headers": MappingProxyType( + {"shortInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "40000", + "-40000", + "-9223372000000000000", + "9223372000000000000", + "123000000000000000000000", + ) + } + ), + "tags": ("underflow/overflow",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyShortMalformedValueRejected", + "documentation": "Malformed values in the body should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedShort/1", + "body": '{ "shortInBody" : $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + '"123"', + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + '"Infinity"', + "-Infinity", + '"-Infinity"', + "NaN", + '"NaN"', + ), + "tag": ( + "string_coercion", + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "string_inf", + "negative_inf", + "string_negative_inf", + "nan", + "string_nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathShortMalformedValueRejected", + "documentation": "Malformed values in the path should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + {"method": "POST", "uri": "/MalformedShort/$value:L"} + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryShortMalformedValueRejected", + "documentation": "Malformed values in query parameters should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedShort/1", + "queryParams": ("shortInQuery=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderShortMalformedValueRejected", + "documentation": "Malformed values in headers should be rejected", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedShort/1", + "headers": MappingProxyType( + {"shortInHeader": "$value:L"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1.001", + "2ABC", + "0x42", + "Infinity", + "-Infinity", + "NaN", + ), + "tag": ( + "boolean_coercion", + "float_truncation", + "trailing_chars", + "hex", + "inf", + "negative_inf", + "nan", + ), + } + ), + "tags": ("$tag:L",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedShort/{shortInPath}", "method": "POST"} + ), + ), + ], +) + +MALFORMED_STRING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedStringInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "blob": { + "target": JSON_HEADER_STRING, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="amz-media-typed-header" + ) + ], + } + }, +) + +MALFORMED_STRING_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedStringOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_STRING = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedString"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHeaderMalformedStringInvalidBase64MediaType", + "documentation": "When string with the mediaType trait is bound to a header, its value\nmust be base64 encoded. The server should reject values that aren't\nvalid base64 out of hand.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedString", + "headers": MappingProxyType( + { + "content-type": "application/json", + "amz-media-typed-header": "$value:L", + } + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("xyz", "YmxvYg=", "[][]", "-_==")} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/MalformedString", "method": "POST"}), + ), + ], +) + +MALFORMED_TIMESTAMP_BODY_DATE_TIME_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampBodyDateTimeInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time"), + Trait.new(id=ShapeID("smithy.api#required")), + ], + } + }, +) + +MALFORMED_TIMESTAMP_BODY_DATE_TIME_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampBodyDateTimeOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_BODY_DATE_TIME = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampBodyDateTime"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyTimestampDateTimeRejectsHttpDate", + "documentation": "When the format is date-time, IMF-fixdate timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyDateTime", + "body": '{ "timestamp": $value:S }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("Tue, 29 Apr 2014 18:30:38 GMT",)} + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyTimestampDateTimeRejectsEpochSeconds", + "documentation": "When the format is date-time, epoch-seconds timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyDateTime", + "body": '{ "timestamp": $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1515531081.1234", "1515531081")} + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyTimestampDateTimeRejectsUTCOffsets", + "documentation": "When the format is date-time, RFC 3339 timestamps with a UTC offset are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyDateTime", + "body": '{ "timestamp": $value:S }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1996-12-19T16:39:57-08:00",)} + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyTimestampDateTimeRejectsDifferent8601Formats", + "documentation": "When the format is date-time, maybe-valid ISO-8601 date-times not conforming to RFC 3339\nare rejected with a 400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyDateTime", + "body": '{ "timestamp": $value:S }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1996-12-19T16:39:57+00", + "1996-12-19T16:39:57+00Z", + "1996-12-19T16:39:57", + "1996-12-19T163957", + "19961219T163957Z", + "19961219T163957", + "19961219T16:39:57Z", + "19961219T16:39:57", + "1996-12-19T16:39Z", + "1996-12-19T16:39", + "1996-12-19T1639", + "1996-12-19T16Z", + "1996-12-19T16", + "1996-12-19 16:39:57Z", + "2011-12-03T10:15:30+01:00[Europe/Paris]", + ) + } + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampBodyDateTime", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_BODY_DEFAULT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampBodyDefaultInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + } + }, +) + +MALFORMED_TIMESTAMP_BODY_DEFAULT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampBodyDefaultOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_BODY_DEFAULT = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampBodyDefault"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyTimestampDefaultRejectsDateTime", + "documentation": "By default, RFC3339 timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyDefault", + "body": '{ "timestamp": $value:S }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1985-04-12T23:20:50.52Z", + "1985-04-12T23:20:50Z", + "1996-12-19T16:39:57-08:00", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyTimestampDefaultRejectsStringifiedEpochSeconds", + "documentation": "By default, epoch second timestamps as strings are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyDefault", + "body": '{ "timestamp": $value:S }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1515531081.1234", "1515531081")} + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyTimestampDefaultRejectsMalformedEpochSeconds", + "documentation": "Invalid values for epoch seconds are rejected with a 400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyDefault", + "body": '{ "timestamp": $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1515531081ABC", + "0x42", + "1515531081.123.456", + "Infinity", + '"Infinity"', + "-Infinity", + '"-Infinity"', + "NaN", + '"NaN"', + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyTimestampDefaultRejectsHttpDate", + "documentation": "By default, IMF-fixdate timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyDefault", + "body": '{ "timestamp": $value:S }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("Tue, 29 Apr 2014 18:30:38 GMT",)} + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampBodyDefault", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_BODY_HTTP_DATE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampBodyHttpDateInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date"), + Trait.new(id=ShapeID("smithy.api#required")), + ], + } + }, +) + +MALFORMED_TIMESTAMP_BODY_HTTP_DATE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampBodyHttpDateOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_BODY_HTTP_DATE = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampBodyHttpDate"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonBodyTimestampHttpDateRejectsDateTime", + "documentation": "When the format is http-date, RFC3339 timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyHttpDate", + "body": '{ "timestamp": $value:S }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1985-04-12T23:20:50.52Z", + "1985-04-12T23:20:50Z", + "1996-12-19T16:39:57-08:00", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonBodyTimestampHttpDateRejectsEpoch", + "documentation": "When the format is http-date, epoch-seconds timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampBodyHttpDate", + "body": '{ "timestamp": $value:L }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1515531081.1234", "1515531081")} + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampBodyHttpDate", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_HEADER_DATE_TIME_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampHeaderDateTimeInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time"), + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="timestamp"), + Trait.new(id=ShapeID("smithy.api#required")), + ], + } + }, +) + +MALFORMED_TIMESTAMP_HEADER_DATE_TIME_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampHeaderDateTimeOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_HEADER_DATE_TIME = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampHeaderDateTime"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHeaderTimestampDateTimeRejectsHttpDate", + "documentation": "When the format is date-time, IMF-fixdate timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampHeaderDateTime", + "headers": MappingProxyType({"timestamp": "$value:L"}), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("Tue, 29 Apr 2014 18:30:38 GMT",)} + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderTimestampDateTimeRejectsEpochSeconds", + "documentation": "When the format is date-time, epoch-seconds timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampHeaderDateTime", + "headers": MappingProxyType({"timestamp": "$value:L"}), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1515531081.1234", "1515531081")} + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderTimestampDateTimeRejectsDifferent8601Formats", + "documentation": "When the format is date-time, maybe-valid ISO-8601 date-times not conforming to RFC 3339\nare rejected with a 400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampHeaderDateTime", + "headers": MappingProxyType({"timestamp": "$value:L"}), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1996-12-19T16:39:57+00", + "1996-12-19T16:39:57+00Z", + "1996-12-19T16:39:57", + "1996-12-19T163957", + "19961219T163957Z", + "19961219T163957", + "19961219T16:39:57Z", + "19961219T16:39:57", + "1996-12-19T16:39Z", + "1996-12-19T16:39", + "1996-12-19T1639", + "1996-12-19T16Z", + "1996-12-19T16", + "1996-12-19 16:39:57Z", + "2011-12-03T10:15:30+01:00[Europe/Paris]", + ) + } + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampHeaderDateTime", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_HEADER_DEFAULT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampHeaderDefaultInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="timestamp"), + Trait.new(id=ShapeID("smithy.api#required")), + ], + } + }, +) + +MALFORMED_TIMESTAMP_HEADER_DEFAULT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampHeaderDefaultOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_HEADER_DEFAULT = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampHeaderDefault"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHeaderTimestampDefaultRejectsDateTime", + "documentation": "By default, RFC3339 timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampHeaderDefault", + "headers": MappingProxyType({"timestamp": "$value:L"}), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1985-04-12T23:20:50.52Z", + "1985-04-12T23:20:50Z", + "1996-12-19T16:39:57-08:00", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderTimestampDefaultRejectsEpochSeconds", + "documentation": "By default, epoch second timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampHeaderDefault", + "headers": MappingProxyType({"timestamp": "$value:L"}), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1515531081.1234", "1515531081")} + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampHeaderDefault", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_HEADER_EPOCH_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampHeaderEpochInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ), + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="timestamp"), + Trait.new(id=ShapeID("smithy.api#required")), + ], + } + }, +) + +MALFORMED_TIMESTAMP_HEADER_EPOCH_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampHeaderEpochOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_HEADER_EPOCH = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampHeaderEpoch"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHeaderTimestampEpochRejectsDateTime", + "documentation": "When the format is epoch-seconds, RFC3339 timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampHeaderEpoch", + "headers": MappingProxyType({"timestamp": "$value:L"}), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1985-04-12T23:20:50.52Z", + "1985-04-12T23:20:50Z", + "1996-12-19T16:39:57-08:00", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderTimestampEpochRejectsHttpDate", + "documentation": "When the format is epoch-seconds, IMF-fixdate timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampHeaderEpoch", + "headers": MappingProxyType({"timestamp": "$value:L"}), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("Tue, 29 Apr 2014 18:30:38 GMT",)} + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonHeaderTimestampEpochRejectsMalformedValues", + "documentation": "Invalid values for epoch seconds are rejected with a 400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampHeaderEpoch", + "headers": MappingProxyType({"timestamp": "$value:L"}), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1515531081ABC", + "0x42", + "1515531081.123.456", + "Infinity", + "-Infinity", + "NaN", + ) + } + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampHeaderEpoch", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_PATH_DEFAULT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampPathDefaultInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + } + }, +) + +MALFORMED_TIMESTAMP_PATH_DEFAULT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampPathDefaultOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_PATH_DEFAULT = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampPathDefault"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonPathTimestampDefaultRejectsHttpDate", + "documentation": "By default, IMF-fixdate timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampPathDefault/$value:L", + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "Tue%2C%2029%20Apr%202014%2018%3A30%3A38%20GMT", + "Sun%2C%2002%20Jan%202000%2020%3A34%3A56.000%20GMT", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathTimestampDefaultRejectsEpochSeconds", + "documentation": "By default, epoch second timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampPathDefault/$value:L", + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1515531081.1234", "1515531081")} + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathTimestampDefaultRejectsUTCOffsets", + "documentation": "UTC offsets must be rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampPathDefault/1996-12-19T16%3A39%3A57-08%3A00", + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathTimestampDefaultRejectsDifferent8601Formats", + "documentation": "By default, maybe-valid ISO-8601 date-times not conforming to RFC 3339\nare rejected with a 400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampPathDefault/$value:L", + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1996-12-19T16%3A39%3A57%2B00", + "1996-12-19T16%3A39%3A57%2B00Z", + "1996-12-19T16%3A39%3A57", + "1996-12-19T163957", + "19961219T163957Z", + "19961219T163957", + "19961219T16%3A39%3A57Z", + "19961219T16%3A39%3A57", + "1996-12-19T16%3A39Z", + "1996-12-19T16%3A39", + "1996-12-19T1639", + "1996-12-19T16Z", + "1996-12-19T16", + "1996-12-19%2016%3A39%3A57Z", + "2011-12-03T10%3A15%3A30%2B01%3A00%5BEurope%2FParis%5D", + ) + } + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampPathDefault/{timestamp}", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_PATH_EPOCH_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampPathEpochInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ), + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + } + }, +) + +MALFORMED_TIMESTAMP_PATH_EPOCH_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampPathEpochOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_PATH_EPOCH = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampPathEpoch"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonPathTimestampEpochRejectsDateTime", + "documentation": "When the format is epoch-seconds, RFC3339 timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampPathEpoch/$value:L", + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1985-04-12T23%3A20%3A50.52Z", + "1985-04-12T23%3A20%3A50Z", + "1996-12-19T16%3A39%3A57-08%3A00", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathTimestampEpochRejectsHttpDate", + "documentation": "When the format is epoch-seconds, IMF-fixdate timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampPathEpoch/$value:L", + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "Tue%2C%2029%20Apr%202014%2018%3A30%3A38%20GMT", + "Sun%2C%2002%20Jan%202000%2020%3A34%3A56.000%20GMT", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathTimestampEpochRejectsMalformedValues", + "documentation": "Invalid values for epoch seconds are rejected with a 400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampPathEpoch/$value:L", + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1515531081ABC", + "0x42", + "1515531081.123.456", + "Infinity", + "-Infinity", + "NaN", + ) + } + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampPathEpoch/{timestamp}", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_PATH_HTTP_DATE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampPathHttpDateInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date"), + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpLabel")), + ], + } + }, +) + +MALFORMED_TIMESTAMP_PATH_HTTP_DATE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampPathHttpDateOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_PATH_HTTP_DATE = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampPathHttpDate"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonPathTimestampHttpDateRejectsDateTime", + "documentation": "When the format is http-date, RFC3339 timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampPathHttpDate/$value:L", + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1985-04-12T23%3A20%3A50.52Z", + "1985-04-12T23%3A20%3A50Z", + "1996-12-19T16%3A39%3A57-08%3A00", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonPathTimestampHttpDateRejectsEpochSeconds", + "documentation": "When the format is http-date, epoch second timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampPathHttpDate/$value:L", + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1515531081.1234", "1515531081")} + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampPathHttpDate/{timestamp}", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_QUERY_DEFAULT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampQueryDefaultInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="timestamp"), + ], + } + }, +) + +MALFORMED_TIMESTAMP_QUERY_DEFAULT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampQueryDefaultOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_QUERY_DEFAULT = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampQueryDefault"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonQueryTimestampDefaultRejectsHttpDate", + "documentation": "By default, IMF-fixdate timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampQueryDefault", + "queryParams": ("timestamp=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "Tue%2C%2029%20Apr%202014%2018%3A30%3A38%20GMT", + "Sun%2C%2002%20Jan%202000%2020%3A34%3A56.000%20GMT", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryTimestampDefaultRejectsEpochSeconds", + "documentation": "By default, epoch second timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampQueryDefault", + "queryParams": ("timestamp=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1515531081.1234", "1515531081")} + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryTimestampDefaultRejectsUTCOffsets", + "documentation": "UTC offsets must be rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampQueryDefault", + "queryParams": ("timestamp=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryTimestampDefaultRejectsDifferent8601Formats", + "documentation": "By default, maybe-valid ISO-8601 date-times not conforming to RFC 3339\nare rejected with a 400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampQueryDefault", + "queryParams": ("timestamp=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1996-12-19T16:39:57+00", + "1996-12-19T16:39:57+00Z", + "1996-12-19T16:39:57", + "1996-12-19T163957", + "19961219T163957Z", + "19961219T163957", + "19961219T16:39:57Z", + "19961219T16:39:57", + "1996-12-19T16:39Z", + "1996-12-19T16:39", + "1996-12-19T1639", + "1996-12-19T16Z", + "1996-12-19T16", + "1996-12-19%2016:39:57Z", + "2011-12-03T10:15:30+01:00[Europe/Paris]", + ) + } + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampQueryDefault", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_QUERY_EPOCH_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampQueryEpochInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ), + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="timestamp"), + ], + } + }, +) + +MALFORMED_TIMESTAMP_QUERY_EPOCH_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampQueryEpochOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_QUERY_EPOCH = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampQueryEpoch"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonQueryTimestampEpochRejectsDateTime", + "documentation": "When the format is epoch-seconds, RFC3339 timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampQueryEpoch", + "queryParams": ("timestamp=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1985-04-12T23%3A20%3A50.52Z", + "1985-04-12T23%3A20%3A50Z", + "1996-12-19T16%3A39%3A57-08%3A00", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryTimestampEpochRejectsHttpDate", + "documentation": "When the format is epoch-seconds, IMF-fixdate timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampQueryEpoch", + "queryParams": ("timestamp=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "Tue%2C%2029%20Apr%202014%2018%3A30%3A38%20GMT", + "Sun%2C%2002%20Jan%202000%2020%3A34%3A56.000%20GMT", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryTimestampEpochRejectsMalformedValues", + "documentation": "Invalid values for epoch seconds are rejected with a 400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampQueryEpoch", + "queryParams": ("timestamp=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "true", + "1515531081ABC", + "0x42", + "1515531081.123.456", + "Infinity", + "-Infinity", + "NaN", + ) + } + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampQueryEpoch", "method": "POST"} + ), + ), + ], +) + +MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampQueryHttpDateInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "timestamp": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date"), + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="timestamp"), + ], + } + }, +) + +MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampQueryHttpDateOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_TIMESTAMP_QUERY_HTTP_DATE = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedTimestampQueryHttpDate"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonQueryTimestampHttpDateRejectsDateTime", + "documentation": "When the format is http-date, RFC3339 timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampQueryHttpDate", + "queryParams": ("timestamp=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + { + "value": ( + "1985-04-12T23%3A20%3A50.52Z", + "1985-04-12T23%3A20%3A50Z", + "1996-12-19T16%3A39%3A57-08%3A00", + ) + } + ), + "tags": ("timestamp",), + } + ), + MappingProxyType( + { + "id": "RestJsonQueryTimestampHttpDateRejectsEpochSeconds", + "documentation": "When the format is http-date, epoch second timestamps are rejected with a\n400 SerializationException", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedTimestampQueryHttpDate", + "queryParams": ("timestamp=$value:L",), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + "testParameters": MappingProxyType( + {"value": ("1515531081.1234", "1515531081")} + ), + "tags": ("timestamp",), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/MalformedTimestampQueryHttpDate", "method": "POST"} + ), + ), + ], +) + +SIMPLE_UNION = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SimpleUnion"), + shape_type=ShapeType.UNION, + members={"int": {"target": INTEGER}, "string": {"target": STRING}}, +) + +MALFORMED_UNION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedUnionInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"union": {"target": SIMPLE_UNION}}, +) + +MALFORMED_UNION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MalformedUnionOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +MALFORMED_UNION = Schema( + id=ShapeID("aws.protocoltests.restjson#MalformedUnion"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("UnstableTrait",)), + Trait.new( + id=ShapeID("smithy.test#httpMalformedRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonMalformedUnionMultipleFieldsSet", + "documentation": "When the union has multiple fields set, the response should be a 400\nSerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedUnion", + "body": '{ "union" : { "int": 2, "string": "three" } }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonMalformedUnionKnownAndUnknownFieldsSet", + "documentation": "When the union has multiple fields set, even when only one is modeled,\nthe response should be a 400 SerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedUnion", + "body": '{ "union" : { "int": 2, "unknownField": "three" } }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonMalformedUnionNoFieldsSet", + "documentation": "When the union has no fields set, the response should be a 400\nSerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedUnion", + "body": '{ "union" : { "int": null } }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonMalformedUnionEmptyObjectNoFieldsSet", + "documentation": "When the union is an empty object, it has no fields set, so the\nresponse should be a 400 SerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedUnion", + "body": '{ "union" : { } }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonMalformedUnionValueIsArray", + "documentation": "When the union value is actually an array, the response should be a 400\nSerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedUnion", + "body": '{ "union" : ["int"] }', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonMalformedUnionUnknownMember", + "documentation": "When an unknown union member is received, the response should be a 400\nSerializationException.", + "protocol": "aws.protocols#restJson1", + "request": MappingProxyType( + { + "method": "POST", + "uri": "/MalformedUnion", + "body": '{\n "union": {\n "unknown": "hello"\n }\n}', + "headers": MappingProxyType( + {"content-type": "application/json"} + ), + } + ), + "response": MappingProxyType( + { + "code": 400, + "headers": MappingProxyType( + {"x-amzn-errortype": "SerializationException"} + ), + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/MalformedUnion", "method": "POST"}), + ), + ], +) + +MEDIA_TYPE_HEADER_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MediaTypeHeaderInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "json": { + "target": JSON_VALUE, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Json")], + } + }, +) + +MEDIA_TYPE_HEADER_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#MediaTypeHeaderOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "json": { + "target": JSON_VALUE, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Json")], + } + }, +) + +MEDIA_TYPE_HEADER = Schema( + id=ShapeID("aws.protocoltests.restjson#MediaTypeHeader"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "MediaTypeHeaderInputBase64", + "documentation": "Headers that target strings with a mediaType are base64 encoded", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/MediaTypeHeader", + "headers": MappingProxyType({"X-Json": "dHJ1ZQ=="}), + "body": "", + "params": MappingProxyType({"json": "true"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "MediaTypeHeaderOutputBase64", + "documentation": "Headers that target strings with a mediaType are base64 encoded", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType({"X-Json": "dHJ1ZQ=="}), + "params": MappingProxyType({"json": "true"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/MediaTypeHeader", "method": "GET"}), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +NO_INPUT_AND_NO_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NoInputAndNoOutputInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +NO_INPUT_AND_NO_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NoInputAndNoOutputOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +NO_INPUT_AND_NO_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.restjson#NoInputAndNoOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonNoInputAndNoOutput", + "documentation": "No input serializes no payload. When clients do not need to\nserialize any data in the payload, they should omit a payload\naltogether.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/NoInputAndNoOutput", + "body": "", + } + ), + MappingProxyType( + { + "id": "RestJsonNoInputAllowsAccept", + "documentation": "Servers should allow the accept header to be set to the\ndefault content-type.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/NoInputAndNoOutput", + "body": "", + "headers": MappingProxyType({"Accept": "application/json"}), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonNoInputAndNoOutput", + "documentation": "When an operation does not define output, the service will respond\nwith an empty payload, and may optionally include the content-type\nheader.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/NoInputAndNoOutput", "method": "POST"}), + ), + ], +) + +NO_INPUT_AND_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NoInputAndOutputInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +NO_INPUT_AND_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NoInputAndOutputOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], +) + +NO_INPUT_AND_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.restjson#NoInputAndOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonNoInputAndOutput", + "documentation": "No input serializes no payload. When clients do not need to\nserialize any data in the payload, they should omit a payload\naltogether.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/NoInputAndOutputOutput", + "body": "", + } + ), + MappingProxyType( + { + "id": "RestJsonNoInputAndOutputAllowsAccept", + "documentation": "Servers should allow the accept header to be set to the\ndefault content-type.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/NoInputAndOutputOutput", + "body": "", + "headers": MappingProxyType({"Accept": "application/json"}), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonNoInputAndOutputWithJson", + "documentation": "Operations that define output and do not bind anything to\nthe payload return a JSON object in the response.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonNoInputAndOutputNoPayload", + "documentation": "This test is similar to RestJsonNoInputAndOutputWithJson, but\nit ensures that clients can gracefully handle responses that\nomit a JSON payload.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "", + "appliesTo": "client", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/NoInputAndOutputOutput", "method": "POST"} + ), + ), + ], +) + +NULL_AND_EMPTY_HEADERS_CLIENT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NullAndEmptyHeadersClientInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#NullAndEmptyHeadersIO", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "a": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-A")], + }, + "b": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-B")], + }, + "c": { + "target": STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-C")], + }, + }, +) + +NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NullAndEmptyHeadersClientOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#NullAndEmptyHeadersIO", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "a": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-A")], + }, + "b": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-B")], + }, + "c": { + "target": STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-C")], + }, + }, +) + +NULL_AND_EMPTY_HEADERS_CLIENT = Schema( + id=ShapeID("aws.protocoltests.restjson#NullAndEmptyHeadersClient"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonNullAndEmptyHeaders", + "documentation": "Do not send null values, but do send empty strings and empty lists over the wire in headers", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/NullAndEmptyHeadersClient", + "forbidHeaders": ("X-A",), + "headers": MappingProxyType({"X-B": "", "X-C": ""}), + "body": "", + "params": MappingProxyType({"a": None, "b": "", "c": ()}), + "appliesTo": "client", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/NullAndEmptyHeadersClient", "method": "GET"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +NULL_AND_EMPTY_HEADERS_SERVER_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NullAndEmptyHeadersServerInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#NullAndEmptyHeadersIO", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "a": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-A")], + }, + "b": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-B")], + }, + "c": { + "target": STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-C")], + }, + }, +) + +NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#NullAndEmptyHeadersServerOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#NullAndEmptyHeadersIO", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "a": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-A")], + }, + "b": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-B")], + }, + "c": { + "target": STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-C")], + }, + }, +) + +NULL_AND_EMPTY_HEADERS_SERVER = Schema( + id=ShapeID("aws.protocoltests.restjson#NullAndEmptyHeadersServer"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new(id=ShapeID("smithy.api#tags"), value=("server-only",)), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonNullAndEmptyHeaders", + "documentation": "Do not send null values, but do send empty strings and empty lists over the wire in headers", + "protocol": "aws.protocols#restJson1", + "code": 200, + "forbidHeaders": ("X-A",), + "headers": MappingProxyType({"X-B": "", "X-C": ""}), + "params": MappingProxyType({"a": None, "b": "", "c": ()}), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/NullAndEmptyHeadersServer", "method": "GET"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OmitsNullSerializesEmptyStringInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "nullValue": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Null")], + }, + "emptyString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="Empty")], + }, + }, +) + +OMITS_NULL_SERIALIZES_EMPTY_STRING_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OmitsNullSerializesEmptyStringOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +OMITS_NULL_SERIALIZES_EMPTY_STRING = Schema( + id=ShapeID("aws.protocoltests.restjson#OmitsNullSerializesEmptyString"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonOmitsNullQuery", + "documentation": "Omits null query values", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/OmitsNullSerializesEmptyString", + "body": "", + "params": MappingProxyType({"nullValue": None}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonSerializesEmptyQueryValue", + "documentation": "Serializes empty query strings", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/OmitsNullSerializesEmptyString", + "body": "", + "queryParams": ("Empty=",), + "params": MappingProxyType({"emptyString": ""}), + } + ), + MappingProxyType( + { + "id": "RestJsonServersAcceptStaticQueryParamAsEmptyString", + "documentation": "Servers accept static query params as empty strings.", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/OmitsNullSerializesEmptyString", + "body": "", + "queryParams": ("Empty",), + "params": MappingProxyType({"emptyString": ""}), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/OmitsNullSerializesEmptyString", "method": "GET"} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +OMITS_SERIALIZING_EMPTY_LISTS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OmitsSerializingEmptyListsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "queryStringList": { + "target": STRING_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="StringList") + ], + }, + "queryIntegerList": { + "target": INTEGER_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="IntegerList") + ], + }, + "queryDoubleList": { + "target": DOUBLE_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="DoubleList") + ], + }, + "queryBooleanList": { + "target": BOOLEAN_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="BooleanList") + ], + }, + "queryTimestampList": { + "target": TIMESTAMP_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="TimestampList") + ], + }, + "queryEnumList": { + "target": FOO_ENUM_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="EnumList")], + }, + "queryIntegerEnumList": { + "target": INTEGER_ENUM_LIST, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="IntegerEnumList") + ], + }, + }, +) + +OMITS_SERIALIZING_EMPTY_LISTS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OmitsSerializingEmptyListsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +OMITS_SERIALIZING_EMPTY_LISTS = Schema( + id=ShapeID("aws.protocoltests.restjson#OmitsSerializingEmptyLists"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonOmitsEmptyListQueryValues", + "documentation": "Supports omitting empty lists.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/OmitsSerializingEmptyLists", + "body": "", + "queryParams": (), + "params": MappingProxyType( + { + "queryStringList": (), + "queryIntegerList": (), + "queryDoubleList": (), + "queryBooleanList": (), + "queryTimestampList": (), + "queryEnumList": (), + "queryIntegerEnumList": (), + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/OmitsSerializingEmptyLists", "method": "POST"} + ), + ), + ], +) + +OPERATION_WITH_DEFAULTS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OperationWithDefaultsInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "defaults": {"target": DEFAULTS}, + "clientOptionalDefaults": {"target": CLIENT_OPTIONAL_DEFAULTS}, + "topLevelDefault": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "otherTopLevelDefault": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + }, +) + +OPERATION_WITH_DEFAULTS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OperationWithDefaultsOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "defaultString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "defaultBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=True)], + }, + "defaultList": { + "target": TEST_STRING_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "defaultDocumentMap": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + "defaultDocumentString": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="hi")], + }, + "defaultDocumentBoolean": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=True)], + }, + "defaultDocumentList": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "defaultNullDocument": { + "target": DOCUMENT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=None)], + }, + "defaultTimestamp": { + "target": TIMESTAMP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "defaultBlob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="YWJj")], + }, + "defaultByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "defaultShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "defaultInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=10)], + }, + "defaultLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=100)], + }, + "defaultFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1.0)], + }, + "defaultDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1.0)], + }, + "defaultMap": { + "target": TEST_STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + "defaultEnum": { + "target": TEST_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="FOO")], + }, + "defaultIntEnum": { + "target": TEST_INT_ENUM, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=1)], + }, + "emptyString": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="")], + }, + "falseBoolean": { + "target": BOOLEAN, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=False)], + }, + "emptyBlob": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value="")], + }, + "zeroByte": { + "target": BYTE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroShort": { + "target": SHORT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroInteger": { + "target": INTEGER, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroLong": { + "target": LONG, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0)], + }, + "zeroFloat": { + "target": FLOAT, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0.0)], + }, + "zeroDouble": { + "target": DOUBLE, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=0.0)], + }, + }, +) + +OPERATION_WITH_DEFAULTS = Schema( + id=ShapeID("aws.protocoltests.restjson#OperationWithDefaults"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonClientPopulatesDefaultValuesInInput", + "documentation": "Client populates default values in input.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/OperationWithDefaults", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "defaults": {\n "defaultString": "hi",\n "defaultBoolean": true,\n "defaultList": [],\n "defaultDocumentMap": {},\n "defaultDocumentString": "hi",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": [],\n "defaultTimestamp": 0,\n "defaultBlob": "YWJj",\n "defaultByte": 1,\n "defaultShort": 1,\n "defaultInteger": 10,\n "defaultLong": 100,\n "defaultFloat": 1.0,\n "defaultDouble": 1.0,\n "defaultMap": {},\n "defaultEnum": "FOO",\n "defaultIntEnum": 1,\n "emptyString": "",\n "falseBoolean": false,\n "emptyBlob": "",\n "zeroByte": 0,\n "zeroShort": 0,\n "zeroInteger": 0,\n "zeroLong": 0,\n "zeroFloat": 0.0,\n "zeroDouble": 0.0\n }\n}', + "params": MappingProxyType({"defaults": MappingProxyType({})}), + } + ), + MappingProxyType( + { + "id": "RestJsonClientSkipsTopLevelDefaultValuesInInput", + "documentation": "Client skips top level default values in input.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/OperationWithDefaults", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": "{\n}", + "params": MappingProxyType({}), + } + ), + MappingProxyType( + { + "id": "RestJsonClientUsesExplicitlyProvidedMemberValuesOverDefaults", + "documentation": "Client uses explicitly provided member values over defaults", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/OperationWithDefaults", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "defaults": MappingProxyType( + { + "defaultString": "bye", + "defaultBoolean": True, + "defaultList": ("a",), + "defaultDocumentMap": MappingProxyType( + {"name": "Jack"} + ), + "defaultDocumentString": "bye", + "defaultDocumentBoolean": True, + "defaultDocumentList": ("b",), + "defaultNullDocument": "notNull", + "defaultTimestamp": 1, + "defaultBlob": "hi", + "defaultByte": 2, + "defaultShort": 2, + "defaultInteger": 20, + "defaultLong": 200, + "defaultFloat": 2.0, + "defaultDouble": 2.0, + "defaultMap": MappingProxyType( + {"name": "Jack"} + ), + "defaultEnum": "BAR", + "defaultIntEnum": 2, + "emptyString": "foo", + "falseBoolean": True, + "emptyBlob": "hi", + "zeroByte": 1, + "zeroShort": 1, + "zeroInteger": 1, + "zeroLong": 1, + "zeroFloat": 1.0, + "zeroDouble": 1.0, + } + ) + } + ), + "body": '{\n "defaults": {\n "defaultString": "bye",\n "defaultBoolean": true,\n "defaultList": ["a"],\n "defaultDocumentMap": {"name": "Jack"},\n "defaultDocumentString": "bye",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": ["b"],\n "defaultNullDocument": "notNull",\n "defaultTimestamp": 1,\n "defaultBlob": "aGk=",\n "defaultByte": 2,\n "defaultShort": 2,\n "defaultInteger": 20,\n "defaultLong": 200,\n "defaultFloat": 2.0,\n "defaultDouble": 2.0,\n "defaultMap": {"name": "Jack"},\n "defaultEnum": "BAR",\n "defaultIntEnum": 2,\n "emptyString": "foo",\n "falseBoolean": true,\n "emptyBlob": "aGk=",\n "zeroByte": 1,\n "zeroShort": 1,\n "zeroInteger": 1,\n "zeroLong": 1,\n "zeroFloat": 1.0,\n "zeroDouble": 1.0\n }\n}', + } + ), + MappingProxyType( + { + "id": "RestJsonServerPopulatesDefaultsWhenMissingInRequestBody", + "documentation": "Server populates default values when missing in request body.", + "appliesTo": "server", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/OperationWithDefaults", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n"defaults": {}\n}', + "params": MappingProxyType( + { + "defaults": MappingProxyType( + { + "defaultString": "hi", + "defaultBoolean": True, + "defaultList": (), + "defaultDocumentMap": MappingProxyType({}), + "defaultDocumentString": "hi", + "defaultDocumentBoolean": True, + "defaultDocumentList": (), + "defaultTimestamp": 0, + "defaultBlob": "abc", + "defaultByte": 1, + "defaultShort": 1, + "defaultInteger": 10, + "defaultLong": 100, + "defaultFloat": 1.0, + "defaultDouble": 1.0, + "defaultMap": MappingProxyType({}), + "defaultEnum": "FOO", + "defaultIntEnum": 1, + "emptyString": "", + "falseBoolean": False, + "emptyBlob": "", + "zeroByte": 0, + "zeroShort": 0, + "zeroInteger": 0, + "zeroLong": 0, + "zeroFloat": 0.0, + "zeroDouble": 0.0, + } + ), + "topLevelDefault": "hi", + "otherTopLevelDefault": 0, + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonClientUsesExplicitlyProvidedValuesInTopLevel", + "documentation": "Any time a value is provided for a member in the top level of input, it is used, regardless of if its the default.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/OperationWithDefaults", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "topLevelDefault": "hi",\n "otherTopLevelDefault": 0\n}', + "params": MappingProxyType( + {"topLevelDefault": "hi", "otherTopLevelDefault": 0} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonClientIgnoresNonTopLevelDefaultsOnMembersWithClientOptional", + "documentation": "Typically, non top-level members would have defaults filled in, but if they have the clientOptional trait, the defaults should be ignored.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/OperationWithDefaults", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "clientOptionalDefaults": {}\n}', + "params": MappingProxyType( + {"clientOptionalDefaults": MappingProxyType({})} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonClientPopulatesDefaultsValuesWhenMissingInResponse", + "documentation": "Client populates default values when missing in response.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": "{}", + "params": MappingProxyType( + { + "defaultString": "hi", + "defaultBoolean": True, + "defaultList": (), + "defaultDocumentMap": MappingProxyType({}), + "defaultDocumentString": "hi", + "defaultDocumentBoolean": True, + "defaultDocumentList": (), + "defaultTimestamp": 0, + "defaultBlob": "abc", + "defaultByte": 1, + "defaultShort": 1, + "defaultInteger": 10, + "defaultLong": 100, + "defaultFloat": 1.0, + "defaultDouble": 1.0, + "defaultMap": MappingProxyType({}), + "defaultEnum": "FOO", + "defaultIntEnum": 1, + "emptyString": "", + "falseBoolean": False, + "emptyBlob": "", + "zeroByte": 0, + "zeroShort": 0, + "zeroInteger": 0, + "zeroLong": 0, + "zeroFloat": 0.0, + "zeroDouble": 0.0, + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonClientIgnoresDefaultValuesIfMemberValuesArePresentInResponse", + "documentation": "Client ignores default values if member values are present in the response.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "defaultString": "bye",\n "defaultBoolean": false,\n "defaultList": ["a"],\n "defaultDocumentMap": {"name": "Jack"},\n "defaultDocumentString": "bye",\n "defaultDocumentBoolean": false,\n "defaultDocumentList": ["b"],\n "defaultNullDocument": "notNull",\n "defaultTimestamp": 2,\n "defaultBlob": "aGk=",\n "defaultByte": 2,\n "defaultShort": 2,\n "defaultInteger": 20,\n "defaultLong": 200,\n "defaultFloat": 2.0,\n "defaultDouble": 2.0,\n "defaultMap": {"name": "Jack"},\n "defaultEnum": "BAR",\n "defaultIntEnum": 2,\n "emptyString": "foo",\n "falseBoolean": true,\n "emptyBlob": "aGk=",\n "zeroByte": 1,\n "zeroShort": 1,\n "zeroInteger": 1,\n "zeroLong": 1,\n "zeroFloat": 1.0,\n "zeroDouble": 1.0\n}', + "params": MappingProxyType( + { + "defaultString": "bye", + "defaultBoolean": False, + "defaultList": ("a",), + "defaultDocumentMap": MappingProxyType( + {"name": "Jack"} + ), + "defaultDocumentString": "bye", + "defaultDocumentBoolean": False, + "defaultDocumentList": ("b",), + "defaultNullDocument": "notNull", + "defaultTimestamp": 2, + "defaultBlob": "hi", + "defaultByte": 2, + "defaultShort": 2, + "defaultInteger": 20, + "defaultLong": 200, + "defaultFloat": 2.0, + "defaultDouble": 2.0, + "defaultMap": MappingProxyType({"name": "Jack"}), + "defaultEnum": "BAR", + "defaultIntEnum": 2, + "emptyString": "foo", + "falseBoolean": True, + "emptyBlob": "hi", + "zeroByte": 1, + "zeroShort": 1, + "zeroInteger": 1, + "zeroLong": 1, + "zeroFloat": 1.0, + "zeroDouble": 1.0, + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonServerPopulatesDefaultsInResponseWhenMissingInParams", + "documentation": "Server populates default values in response when missing in params.", + "appliesTo": "server", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "defaultString": "hi",\n "defaultBoolean": true,\n "defaultList": [],\n "defaultDocumentMap": {},\n "defaultDocumentString": "hi",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": [],\n "defaultTimestamp": 0,\n "defaultBlob": "YWJj",\n "defaultByte": 1,\n "defaultShort": 1,\n "defaultInteger": 10,\n "defaultLong": 100,\n "defaultFloat": 1.0,\n "defaultDouble": 1.0,\n "defaultMap": {},\n "defaultEnum": "FOO",\n "defaultIntEnum": 1,\n "emptyString": "",\n "falseBoolean": false,\n "emptyBlob": "",\n "zeroByte": 0,\n "zeroShort": 0,\n "zeroInteger": 0,\n "zeroLong": 0,\n "zeroFloat": 0.0,\n "zeroDouble": 0.0\n}', + "params": MappingProxyType({}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/OperationWithDefaults", "method": "POST"}), + ), + ], +) + +TOP_LEVEL = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TopLevel"), + members={ + "dialog": { + "target": DIALOG, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "dialogList": { + "target": DIALOG_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "dialogMap": { + "target": DIALOG_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + }, +) + +OPERATION_WITH_NESTED_STRUCTURE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OperationWithNestedStructureInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "topLevel": { + "target": TOP_LEVEL, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + } + }, +) + +OPERATION_WITH_NESTED_STRUCTURE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OperationWithNestedStructureOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "dialog": { + "target": DIALOG, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + }, + "dialogList": { + "target": DIALOG_LIST, + "traits": [Trait.new(id=ShapeID("smithy.api#default"), value=())], + }, + "dialogMap": { + "target": DIALOG_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#default"))], + }, + }, +) + +OPERATION_WITH_NESTED_STRUCTURE = Schema( + id=ShapeID("aws.protocoltests.restjson#OperationWithNestedStructure"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonClientPopulatesNestedDefaultValuesWhenMissing", + "documentation": "Client populates nested default values when missing.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/OperationWithNestedStructure", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "topLevel": {\n "dialog": {\n "language": "en",\n "greeting": "hi"\n },\n "dialogList": [\n {\n "greeting": "hi"\n },\n {\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n "greeting": "hi"\n },\n "partialEmptyDialog": {\n "language": "en",\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n }\n}', + "params": MappingProxyType( + { + "topLevel": MappingProxyType( + { + "dialog": MappingProxyType({"language": "en"}), + "dialogList": ( + MappingProxyType({}), + MappingProxyType( + {"farewell": MappingProxyType({})} + ), + MappingProxyType( + { + "language": "it", + "greeting": "ciao", + "farewell": MappingProxyType( + {"phrase": "arrivederci"} + ), + } + ), + ), + "dialogMap": MappingProxyType( + { + "emptyDialog": MappingProxyType({}), + "partialEmptyDialog": MappingProxyType( + { + "language": "en", + "farewell": MappingProxyType( + {} + ), + } + ), + "nonEmptyDialog": MappingProxyType( + { + "greeting": "konnichiwa", + "farewell": MappingProxyType( + {"phrase": "sayonara"} + ), + } + ), + } + ), + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonServerPopulatesNestedDefaultsWhenMissingInRequestBody", + "documentation": "Server populates nested default values when missing in request body.", + "appliesTo": "server", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "method": "POST", + "bodyMediaType": "application/json", + "uri": "/OperationWithNestedStructure", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "topLevel": {\n "dialog": {\n "language": "en"\n },\n "dialogList": [\n {\n },\n {\n "farewell": {}\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n },\n "partialEmptyDialog": {\n "language": "en",\n "farewell": {}\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n }\n}', + "params": MappingProxyType( + { + "topLevel": MappingProxyType( + { + "dialog": MappingProxyType( + {"language": "en", "greeting": "hi"} + ), + "dialogList": ( + MappingProxyType({"greeting": "hi"}), + MappingProxyType( + { + "greeting": "hi", + "farewell": MappingProxyType( + {"phrase": "bye"} + ), + } + ), + MappingProxyType( + { + "language": "it", + "greeting": "ciao", + "farewell": MappingProxyType( + {"phrase": "arrivederci"} + ), + } + ), + ), + "dialogMap": MappingProxyType( + { + "emptyDialog": MappingProxyType( + {"greeting": "hi"} + ), + "partialEmptyDialog": MappingProxyType( + { + "language": "en", + "greeting": "hi", + "farewell": MappingProxyType( + {"phrase": "bye"} + ), + } + ), + "nonEmptyDialog": MappingProxyType( + { + "greeting": "konnichiwa", + "farewell": MappingProxyType( + {"phrase": "sayonara"} + ), + } + ), + } + ), + } + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonClientPopulatesNestedDefaultsWhenMissingInResponseBody", + "documentation": "Client populates nested default values when missing in response body.", + "appliesTo": "client", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "dialog": {\n "language": "en"\n },\n "dialogList": [\n {\n },\n {\n "farewell": {}\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n },\n "partialEmptyDialog": {\n "language": "en",\n "farewell": {}\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n}', + "params": MappingProxyType( + { + "dialog": MappingProxyType( + {"language": "en", "greeting": "hi"} + ), + "dialogList": ( + MappingProxyType({"greeting": "hi"}), + MappingProxyType( + { + "greeting": "hi", + "farewell": MappingProxyType( + {"phrase": "bye"} + ), + } + ), + MappingProxyType( + { + "language": "it", + "greeting": "ciao", + "farewell": MappingProxyType( + {"phrase": "arrivederci"} + ), + } + ), + ), + "dialogMap": MappingProxyType( + { + "emptyDialog": MappingProxyType( + {"greeting": "hi"} + ), + "partialEmptyDialog": MappingProxyType( + { + "language": "en", + "greeting": "hi", + "farewell": MappingProxyType( + {"phrase": "bye"} + ), + } + ), + "nonEmptyDialog": MappingProxyType( + { + "greeting": "konnichiwa", + "farewell": MappingProxyType( + {"phrase": "sayonara"} + ), + } + ), + } + ), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonServerPopulatesNestedDefaultValuesWhenMissingInInResponseParams", + "documentation": "Server populates nested default values when missing in response params.", + "appliesTo": "server", + "tags": ("defaults",), + "protocol": "aws.protocols#restJson1", + "code": 200, + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": '{\n "dialog": {\n "language": "en",\n "greeting": "hi"\n },\n "dialogList": [\n {\n "greeting": "hi"\n },\n {\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n "greeting": "hi"\n },\n "partialEmptyDialog": {\n "language": "en",\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n}', + "params": MappingProxyType( + { + "dialog": MappingProxyType({"language": "en"}), + "dialogList": ( + MappingProxyType({}), + MappingProxyType( + {"farewell": MappingProxyType({})} + ), + MappingProxyType( + { + "language": "it", + "greeting": "ciao", + "farewell": MappingProxyType( + {"phrase": "arrivederci"} + ), + } + ), + ), + "dialogMap": MappingProxyType( + { + "emptyDialog": MappingProxyType({}), + "partialEmptyDialog": MappingProxyType( + { + "language": "en", + "farewell": MappingProxyType({}), + } + ), + "nonEmptyDialog": MappingProxyType( + { + "greeting": "konnichiwa", + "farewell": MappingProxyType( + {"phrase": "sayonara"} + ), + } + ), + } + ), + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/OperationWithNestedStructure", "method": "POST"} + ), + ), + ], +) + +OUTPUT_STREAM_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OutputStreamInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +OUTPUT_STREAM_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OutputStreamOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "stream": { + "target": EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + } + }, +) + +OUTPUT_STREAM = Schema( + id=ShapeID("aws.protocoltests.restjson#OutputStream"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"method": "POST", "uri": "/OutputStream"}), + ), + Trait.new( + id=ShapeID("smithy.test#eventStreamTests"), + value=( + MappingProxyType( + { + "id": "BooleanHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"booleanHeader": True} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgC4J9Ws", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "ByteHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + {"headers": MappingProxyType({"byteHeader": 1})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "byteHeader": MappingProxyType({"byte": 1}), + } + ), + "bytes": "AAAASQAAADlvxG1ZDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKYnl0ZUhlYWRlcgIBKFTmjg==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "ShortHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"shortHeader": 2} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "shortHeader": MappingProxyType( + {"short": 2} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMLc2hvcnRIZWFkZXIDAAL1ETsK", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "IntegerHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + {"headers": MappingProxyType({"intHeader": 3})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "intHeader": MappingProxyType( + {"integer": 3} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMJaW50SGVhZGVyBAAAAAPlyUrb", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "LongHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"longHeader": 4294967294} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "longHeader": MappingProxyType( + {"long": 4294967294} + ), + } + ), + "bytes": "AAAAUAAAAEAr7VEyDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKbG9uZ0hlYWRlcgUAAAAA/////udnd/I=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "BlobHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"blobHeader": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "blobHeader": MappingProxyType( + {"blob": "Zm9v"} + ), + } + ), + "bytes": "AAAATQAAAD2dKQ+ADTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMKYmxvYkhlYWRlcgYAA2Zvb5sbbGM=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "StringHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"stringHeader": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "stringHeader": MappingProxyType( + {"string": "foo"} + ), + } + ), + "bytes": "AAAATwAAAD8J5z3MDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMMc3RyaW5nSGVhZGVyBwADZm9vxT+2MA==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "TimestampHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + { + "timestampHeader": "2024-10-31T14:15:14Z" + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "timestampHeader": MappingProxyType( + {"timestamp": "2024-10-31T14:15:14Z"} + ), + } + ), + "bytes": "AAAAVQAAAEWTZyrNDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMPdGltZXN0YW1wSGVhZGVyCAAAAZLi7jFQ6uV3Eg==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "MultipleHeaderOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + { + "booleanHeader": True, + "stringHeader": "foo", + "blobHeader": "bar", + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + "stringHeader": MappingProxyType( + {"string": "foo"} + ), + "blobHeader": MappingProxyType( + {"blob": "YmFy"} + ), + } + ), + "bytes": "AAAAbwAAAF+FlHOQDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgAMc3RyaW5nSGVhZGVyBwADZm9vCmJsb2JIZWFkZXIGAANiYXIDXbo7", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "StringPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "stringPayload": MappingProxyType( + {"payload": "foo"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "stringPayload"} + ), + ":content-type": MappingProxyType( + {"string": "text/plain"} + ), + } + ), + "body": "foo", + "bodyMediaType": "text/plain", + "bytes": "AAAAYAAAAE30fZUJDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcADXN0cmluZ1BheWxvYWQNOmNvbnRlbnQtdHlwZQcACnRleHQvcGxhaW5mb29G1ELr", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "BlobPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "blobPayload": MappingProxyType( + {"payload": "bar"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "blobPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/octet-stream"} + ), + } + ), + "body": "bar", + "bodyMediaType": "application/octet-stream", + "bytes": "AAAAbAAAAFkrV6x1DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAC2Jsb2JQYXlsb2FkDTpjb250ZW50LXR5cGUHABhhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1iYXJv5nGJ", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "StructurePayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "structurePayload": MappingProxyType( + { + "payload": MappingProxyType( + {"structureMember": "foo"} + ) + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "structurePayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"structureMember":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAfwAAAFacqFy2DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAEHN0cnVjdHVyZVBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257InN0cnVjdHVyZU1lbWJlciI6ImZvbyJ9rcIRVA==", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "UnionPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "unionPayload": MappingProxyType( + { + "payload": MappingProxyType( + {"unionMember": "bar"} + ) + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "unionPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"unionMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdwAAAFKrtdNuDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcADHVuaW9uUGF5bG9hZA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbnsidW5pb25NZW1iZXIiOiJiYXIifcZDMD4=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "HeadersAndExplicitPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifTafKXs=", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "HeadersAndImplicitPayloadOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndImplicitPayload": MappingProxyType( + {"header": "foo", "payload": "bar"} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headersAndImplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"payload":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAjQAAAGxoUIY5DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRJbXBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJwYXlsb2FkIjoiYmFyIn15lZtT", + } + ), + ), + } + ), + MappingProxyType( + { + "id": "ServerErrorOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + {"error": MappingProxyType({"message": "foo"})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "exception"} + ), + ":exception-type": MappingProxyType( + {"string": "error"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"message":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdAAAAFObEpkoDTptZXNzYWdlLXR5cGUHAAlleGNlcHRpb24POmV4Y2VwdGlvbi10eXBlBwAFZXJyb3INOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257Im1lc3NhZ2UiOiJmb28ifTua1S8=", + } + ), + ), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "ClientErrorOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + {"error": MappingProxyType({"message": "foo"})} + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "exception"} + ), + ":exception-type": MappingProxyType( + {"string": "error"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + } + ), + "body": '{"message":"foo"}', + "bodyMediaType": "application/json", + "bytes": "AAAAdAAAAFObEpkoDTptZXNzYWdlLXR5cGUHAAlleGNlcHRpb24POmV4Y2VwdGlvbi10eXBlBwAFZXJyb3INOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb257Im1lc3NhZ2UiOiJmb28ifTua1S8=", + } + ), + ), + "expectation": MappingProxyType( + { + "failure": MappingProxyType( + {"errorId": "aws.protocoltests.restjson#ErrorEvent"} + ) + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "ClientUnexpectedErrorOutput", + "documentation": "Clients must be able to handle structured, but unmodeled errors.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "error"} + ), + ":error-code": MappingProxyType( + {"string": "internal-error"} + ), + ":error-message": MappingProxyType( + {"string": "An unknown error occurred."} + ), + } + ), + "bytes": "AAAAbwAAAF+FlHOQDTptZXNzYWdlLXR5cGUHAAVlcnJvcgs6ZXJyb3ItY29kZQcADmludGVybmFsLWVycm9yDjplcnJvci1tZXNzYWdlBwAaQW4gdW5rbm93biBlcnJvciBvY2N1cnJlZC4kun0t", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "MissingMessageTypeOutput", + "documentation": "Clients must reject events that don't contain a :message-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAfwAAAFacqFy2CzpldmVudC10eXBlBwAZaGVhZGVyc0FuZEV4cGxpY2l0UGF5bG9hZA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbgZoZWFkZXIHAANmb297InN0cnVjdHVyZU1lbWJlciI6ImJhciJ98LexJg==", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "MalformedMessageTypeOutput", + "documentation": "Client must reject events that contain a malformed :message-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"blob": "ZXZlbnQ="} + ), + ":event-type": MappingProxyType( + {"string": "headersAndExplicitPayload"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUGAAVldmVudAs6ZXZlbnQtdHlwZQcAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifVwdfzU=", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "MissingEventTypeOutput", + "documentation": "Clients must reject message events that don't contain an :event-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAbQAAAER1MekcDTptZXNzYWdlLXR5cGUHAAVldmVudA06Y29udGVudC10eXBlBwAQYXBwbGljYXRpb24vanNvbgZoZWFkZXIHAANmb297InN0cnVjdHVyZU1lbWJlciI6ImJhciJ9riy0Gg==", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "MalformedEventTypeOutput", + "documentation": "Clients must reject message events that contain a malformed :event-type header.", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headersAndExplicitPayload": MappingProxyType( + { + "header": "foo", + "payload": MappingProxyType( + {"structureMember": "bar"} + ), + } + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + { + "blob": "aGVhZGVyc0FuZEV4cGxpY2l0UGF5bG9hZA==" + } + ), + ":content-type": MappingProxyType( + {"string": "application/json"} + ), + "header": MappingProxyType( + {"string": "foo"} + ), + } + ), + "body": '{"structureMember":"bar"}', + "bodyMediaType": "application/json", + "bytes": "AAAAlQAAAGw4wFp6DTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQYAGWhlYWRlcnNBbmRFeHBsaWNpdFBheWxvYWQNOmNvbnRlbnQtdHlwZQcAEGFwcGxpY2F0aW9uL2pzb24GaGVhZGVyBwADZm9veyJzdHJ1Y3R1cmVNZW1iZXIiOiJiYXIifcP6KLk=", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "ModeledProtocolError", + "protocol": "aws.protocols#restJson1", + "initialResponse": MappingProxyType( + { + "code": 500, + "headers": MappingProxyType( + { + "Content-Type": "application/json", + "X-Amzn-Errortype": "ServiceUnavailableError", + } + ), + "body": '{"message": "foo"}', + "bodyMediaType": "application/json", + } + ), + "initialResponseShape": "smithy.test#InitialHttpResponse", + "expectation": MappingProxyType( + { + "failure": MappingProxyType( + { + "errorId": "aws.protocoltests.restjson#ServiceUnavailableError" + } + ) + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "UnmodeledProtocolError", + "protocol": "aws.protocols#restJson1", + "initialResponse": MappingProxyType( + { + "code": 500, + "headers": MappingProxyType( + {"Content-Type": "text/plain"} + ), + "body": "service unavailable", + "bodyMediaType": "text/plain", + } + ), + "initialResponseShape": "smithy.test#InitialHttpResponse", + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +OUTPUT_STREAM_WITH_INITIAL_RESPONSE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OutputStreamWithInitialResponseInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +OUTPUT_STREAM_WITH_INITIAL_RESPONSE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#OutputStreamWithInitialResponseOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "initialResponseMember": { + "target": STRING, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="initial-response-member" + ), + Trait.new(id=ShapeID("smithy.api#required")), + ], + }, + "stream": { + "target": EVENT_STREAM, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +OUTPUT_STREAM_WITH_INITIAL_RESPONSE = Schema( + id=ShapeID("aws.protocoltests.restjson#OutputStreamWithInitialResponse"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/OutputStreamWithInitialResponse"} + ), + ), + Trait.new( + id=ShapeID("smithy.test#eventStreamTests"), + value=( + MappingProxyType( + { + "id": "InitialResponseOutput", + "protocol": "aws.protocols#restJson1", + "initialResponseParams": MappingProxyType( + {"initialResponseMember": "foo"} + ), + "initialResponse": MappingProxyType( + { + "code": 200, + "headers": MappingProxyType( + {"initial-response-member": "foo"} + ), + } + ), + "initialResponseShape": "smithy.test#InitialHttpResponse", + } + ), + MappingProxyType( + { + "id": "MissingRequiredInitialResponseOutput", + "protocol": "aws.protocols#restJson1", + "events": ( + MappingProxyType( + { + "type": "response", + "params": MappingProxyType( + { + "headers": MappingProxyType( + {"booleanHeader": True} + ) + } + ), + "headers": MappingProxyType( + { + ":message-type": MappingProxyType( + {"string": "event"} + ), + ":event-type": MappingProxyType( + {"string": "headers"} + ), + "booleanHeader": MappingProxyType( + {"boolean": True} + ), + } + ), + "bytes": "AAAASwAAADv7Cl8VDTptZXNzYWdlLXR5cGUHAAVldmVudAs6ZXZlbnQtdHlwZQcAB2hlYWRlcnMNYm9vbGVhbkhlYWRlcgC4J9Ws", + } + ), + ), + "expectation": MappingProxyType( + {"failure": MappingProxyType({})} + ), + "appliesTo": "client", + } + ), + ), + ), + ], +) + +PAYLOAD_CONFIG = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PayloadConfig"), + members={"data": {"target": INTEGER}}, +) + +PLAYER_ACTION = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PlayerAction"), + shape_type=ShapeType.UNION, + members={"quit": {"target": UNIT}}, +) + +POST_PLAYER_ACTION_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PostPlayerActionInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"action": {"target": PLAYER_ACTION}}, +) + +POST_PLAYER_ACTION_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PostPlayerActionOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "action": { + "target": PLAYER_ACTION, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + } + }, +) + +POST_PLAYER_ACTION = Schema( + id=ShapeID("aws.protocoltests.restjson#PostPlayerAction"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonInputUnionWithUnitMember", + "documentation": "Unit types in unions are serialized like normal structures in requests.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/PostPlayerAction", + "body": '{\n "action": {\n "quit": {}\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"action": MappingProxyType({"quit": MappingProxyType({})})} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonOutputUnionWithUnitMember", + "documentation": "Unit types in unions are serialized like normal structures in responses.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "action": {\n "quit": {}\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"action": MappingProxyType({"quit": MappingProxyType({})})} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/PostPlayerAction", "method": "POST"}), + ), + ], +) + +UNION_WITH_JSON_NAME = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#UnionWithJsonName"), + shape_type=ShapeType.UNION, + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#jsonName"), value="FOO")], + }, + "bar": {"target": STRING}, + "baz": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#jsonName"), value="_baz")], + }, + }, +) + +POST_UNION_WITH_JSON_NAME_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PostUnionWithJsonNameInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={"value": {"target": UNION_WITH_JSON_NAME}}, +) + +POST_UNION_WITH_JSON_NAME_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PostUnionWithJsonNameOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "value": { + "target": UNION_WITH_JSON_NAME, + "traits": [Trait.new(id=ShapeID("smithy.api#required"))], + } + }, +) + +POST_UNION_WITH_JSON_NAME = Schema( + id=ShapeID("aws.protocoltests.restjson#PostUnionWithJsonName"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "PostUnionWithJsonNameRequest1", + "documentation": "Tests that jsonName works with union members.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/PostUnionWithJsonName", + "body": '{\n "value": {\n "FOO": "hi"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"value": MappingProxyType({"foo": "hi"})} + ), + } + ), + MappingProxyType( + { + "id": "PostUnionWithJsonNameRequest2", + "documentation": "Tests that jsonName works with union members.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/PostUnionWithJsonName", + "body": '{\n "value": {\n "_baz": "hi"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"value": MappingProxyType({"baz": "hi"})} + ), + } + ), + MappingProxyType( + { + "id": "PostUnionWithJsonNameRequest3", + "documentation": "Tests that jsonName works with union members.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/PostUnionWithJsonName", + "body": '{\n "value": {\n "bar": "hi"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"value": MappingProxyType({"bar": "hi"})} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "PostUnionWithJsonNameResponse1", + "documentation": "Tests that jsonName works with union members.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "value": {\n "FOO": "hi"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"value": MappingProxyType({"foo": "hi"})} + ), + } + ), + MappingProxyType( + { + "id": "PostUnionWithJsonNameResponse2", + "documentation": "Tests that jsonName works with union members.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "value": {\n "_baz": "hi"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"value": MappingProxyType({"baz": "hi"})} + ), + } + ), + MappingProxyType( + { + "id": "PostUnionWithJsonNameResponse3", + "documentation": "Tests that jsonName works with union members.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "value": {\n "bar": "hi"\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"value": MappingProxyType({"bar": "hi"})} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/PostUnionWithJsonName", "method": "POST"}), + ), + ], +) + +PUT_WITH_CONTENT_ENCODING_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PutWithContentEncodingInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "encoding": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="Content-Encoding") + ], + }, + "data": {"target": STRING}, + }, +) + +PUT_WITH_CONTENT_ENCODING_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#PutWithContentEncodingOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +PUT_WITH_CONTENT_ENCODING = Schema( + id=ShapeID("aws.protocoltests.restjson#PutWithContentEncoding"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "SDKAppliedContentEncoding_restJson1", + "documentation": "Compression algorithm encoding is appended to the Content-Encoding header.", + "protocol": "aws.protocols#restJson1", + "params": MappingProxyType( + { + "data": "RjCEL3kBwqPivZUXGiyA5JCujtWgJAkKRlnTEsNYfBRGOS0f7LT6R3bCSOXeJ4auSHzQ4BEZZTklUyj5\n1HEojihShQC2jkQJrNdGOZNSW49yRO0XbnGmeczUHbZqZRelLFKW4xjru9uTuB8lFCtwoGgciFsgqTF8\n5HYcoqINTRxuAwGuRUMoNO473QT0BtCQoKUkAyVaypG0hBZdGNoJhunBfW0d3HWTYlzz9pXElyZhq3C1\n2PDB17GEoOYXmTxDecysmPOdo5z6T0HFhujfeJFIQQ8dirmXcG4F3v0bZdf6AZ3jsiVh6RnEXIPxPbOi\ngIXDWTMUr4Pg3f2LdYCM01eAb2qTdgsEN0MUDhEIfn68I2tnWvcozyUFpg1ez6pyWP8ssWVfFrckREIM\nMb0cTUVqSVSM8bnFiF9SoXM6ZoGMKfX1mT708OYk7SqZ1JlCTkecDJDoR5ED2q2MWKUGR6jjnEV0GtD8\nWJO6AcF0DptY9Hk16Bav3z6c5FeBvrGDrxTFVgRUk8SychzjrcqJ4qskwN8rL3zslC0oqobQRnLFOvwJ\nprSzBIwdH2yAuxokXAdVRa1u9NGNRvfWJfKkwbbVz8yV76RUF9KNhAUmwyYDrLnxNj8ROl8B7dv8Gans\n7Bit52wcdiJyjBW1pAodB7zqqVwtBx5RaSpF7kEMXexYXp9N0J1jlXzdeg5Wgg4pO7TJNr2joiPVAiFf\nefwMMCNBkYx2z7cRxVxCJZMXXzxSKMGgdTN24bJ5UgE0TxyV52RC0wGWG49S1x5jGrvmxKCIgYPs0w3Z\n0I3XcdB0WEj4x4xRztB9Cx2Mc4qFYQdzS9kOioAgNBti1rBySZ8lFZM2zqxvBsJTTJsmcKPr1crqiXjM\noVWdM4ObOO6QA7Pu4c1hT68CrTmbcecjFcxHkgsqdixnFtN6keMGL9Z2YMjZOjYYzbUEwLJqUVWalkIB\nBkgBRqZpzxx5nB5t0qDH35KjsfKM5cinQaFoRq9y9Z82xdCoKZOsUbxZkk1kVmy1jPDCBhkhixkc5PKS\nFoSKTbeK7kuCEZCtR9OfF2k2MqbygGFsFu2sgb1Zn2YdDbaRwRGeaLhswta09UNSMUo8aTixgoYVHxwy\nvraLB6olPSPegeLOnmBeWyKmEfPdbpdGm4ev4vA2AUFuLIeFz0LkCSN0NgQMrr8ALEm1UNpJLReg1ZAX\nzZh7gtQTZUaBVdMJokaJpLk6FPxSA6zkwB5TegSqhrFIsmvpY3VNWmTUq7H0iADdh3dRQ8Is97bTsbwu\nvAEOjh4FQ9wPSFzEtcSJeYQft5GfWYPisDImjjvHVFshFFkNy2nN18pJmhVPoJc456tgbdfEIdGhIADC\n6UPcSSzE1FxlPpILqZrp3i4NvvKoiOa4a8tnALd2XRHHmsvALn2Wmfu07b86gZlu4yOyuUFNoWI6tFvd\nbHnqSJYNQlFESv13gJw609DBzNnrIgBGYBAcDRrIGAnflRKwVDUnDFrUQmE8xNG6jRlyb1p2Y2RrfBtG\ncKqhuGNiT2DfxpY89ektZ98waPhJrFEPJToNH8EADzBorh3T0h4YP1IeLmaI7SOxeuVrk1kjRqMK0rUB\nlUJgJNtCE35jCyoHMwPQlyi78ZaVv8COVQ24zcGpw0MTy6JUsDzAC3jLNY6xCb40SZV9XzG7nWvXA5Ej\nYC1gTXxF4AtFexIdDZ4RJbtYMyXt8LsEJerwwpkfqvDwsiFuqYC6vIn9RoZO5kI0F35XtUITDQYKZ4eq\nWBV0itxTyyR5Rp6g30pZEmEqOusDaIh96CEmHpOBYAQZ7u1QTfzRdysIGMpzbx5gj9Dxm2PO1glWzY7P\nlVqQiBlXSGDOkBkrB6SkiAxknt9zsPdTTsf3r3nid4hdiPrZmGWNgjOO1khSxZSzBdltrCESNnQmlnP5\nZOHA0eSYXwy8j4od5ZmjA3IpFOEPW2MutMbxIbJpg5dIx2x7WxespftenRLgl3CxcpPDcnb9w8LCHBg7\nSEjrEer6Y8wVLFWsQiv6nTdCPZz9cGqwgtCaiHRy8lTWFgdfWd397vw9rduGld3uUFeFRGjYrphqEmHi\nhiG0GhE6wRFVUsGJtvOCYkVREvbEdxPFeJvlAvOcs9HKbtptlTusvYB86vR2bNcIY4f5JZu2X6sGa354\n7LRk0ps2zqYjat3hMR7XDC8KiKceBteFsXoDjfVxTYKelpedTxqWAafrKhaoAVuNM98PSnkuIWGzjSUC\nNsDJTt6vt1D1afBVPWVmnQ7ZQdtEtLIEwAWYjemAztreELIr1E9fPEILm1Ke4KctP9I0I72Dh4eylNZD\n0DEr2Hg7cWFckuZ0Av5d0IPRARXikEGDHl8uh12TXL9v2Uh0ZVSJMEYvxGSbZvkWz8TjWSk3hKA2a7GL\nJm3Ho7e1C34gE1XRGcEthxvURxt4OKBqN3ZNaMIuDTWinoQAutMcUqtm4MoL7RGPiCHUrvTwQPSirsmA\nQmOEu8nOpnP77Fivh9jLGx5ta7nL6jrsWUsBqiN1lzpdPYLRR4mUIAj6sNWiDEk4pkbHSMEcqbWw6Zl7\npsEyPDHalCNhWMA3RSK3skURzQDZ0oBV5W7vjVIZ4d3uCKsk6zrzEI9u5mx7p9RdNKodXfzqYt0ULdtc\n3RW0hIfw2KvrO3BD2QrtgAkfrFBGVvlJSUoh0MvLz8DeXxfuiuq9Ttu7wvsqVI4Piah6WNEXtHHGPJO3\nGhc75Bnv2To4VS2v8rmyKAPIIVTuYBHZN6sZ4FhFzbrslCIdk0eadaU60naqiNWU3CsxplIYGyeThmJ7\n9u4h6Y2OmiPZjFPS2bAzwgAozYTVefII9aEaWZ0hxHZeu1FW7r79dkdO73ZqRfas9u8Z7LLBPCw5pV0F\n5I0pHDgNb6MogoxF4NZJfVtIX1vCHhhVLrXjrYNJU2fD9Fw8kT8Ie2HDBJnqAvYKmryQ1r9ulo3Me3rH\nq9s2Y5uCDxu9iQNhnpwIm57WYGFeqd2fnQeY2IziD3Jgx0KSrmOH0jgi0RwJyfGXaORPq3bQQqljuACo\nkO6io9t5VI8PbNxSHTRbtYiPciUslbT0g7SpCLrRPOBRJ4DDk56pjghpeoUagJ5xJ4wjBzBuXnAGkNnP\nTfpiuz2r3oSBAi8sB9wiYK2z9sp4gZyQsqdVNzAEgKatOxBRBmJCBYpjO98ZQrF83XApPpfFg0ujB2PW\n1iYF9NkgwIKB5oB6KVTOmSKJk11mVermPgeugHbzdd2zUP6fP8fWbhseqk2t8ahGvqjs2CDHFIWXl5jc\nfCknbykE3ANt7lnAfJQ2ddduLGiqrX4HWx6jcWw08Es6BkleO0IDbaWrb95d5isvFlzJsf0TyDIXF4uq\nbBDCi0XPWqtRJ2iqmnJa2GbBe9GmAOWMkBFSilMyC4sR395WSDpD56fx0NGoU6cHrRu9xF2Bgh7RGSfl\nch2GXEeE02fDpSHFNvJBlOEqqfkIX6oCa6KY9NThqeIjYsT184XR2ZI7akXRaw1gMOGpk4FmUxk6WIuX\n4ei1SLQgSdl7OEdRtJklZ76eFrMbkJQ2TDhu8f7mVuiy53GUMIvCrP9xYGZGmCIDm2e4U2BDi3F7C5xK\n3bDZXwlQp6z4BSqTy2OVEWxXUJfjPMOL5Mc7AvDeKtxAS73pVIv0HgHIa4NBAdC7uLG0zXuu1FF6z2XY\nyUhk03fMZhYe7vVxsul3WE7U01fuN8z2y0eKwBW1RFBE1eKIaR9Y01sIWQWbSrfHfDrdZiElhmhHehfs\n0EfrR4sLYdQshJuvhTeKGJDaEhtPQwwJ9mUYGtuCL9RozWx1XI4bHNlzBTW0BVokYiJGlPe7wdxNzJD7\nJgS7Lwv6jGKngVf86imGZyzqwiteWFPdNUoWdTvUPSMO5xIUK9mo5QpwbBOAmyYzVq42o3Qs90N9khEV\nU36LB99fw8PtGHH5wsCHshfauwnNPj0blGXzke0kQ4JNCVH7Jtn0Y0aeejkSxFtwtxoYs6zHl1Lxxpsd\nsw5vBy49CEtoltDW367lVAwDjWdx20msGB7qJCkEDrzu7EXSO22782QX9NBRcN9ppX0C25I0FMA4Wnhz\n9zIpiXRrsTH35jzM8Cjt4EVLGNU3O0HuEvAer3cENnMJtngdrT86ox3fihMQbiuy4Bh4DEcP5in2VjbT\n3qbnoCNvOi8Fmmf7KlGlWAOceL5OHVE5lljjQEMzEQOCEgrk5mDKgwSBJQBNauIDSC1a5iEQjB8Xxp4C\nqeKyyWY9IOntNrtU5ny4lNprHJd36dKFeBLKcGCOvgHBXdOZloMF0YTRExw7hreEO9IoTGVHJ4teWsNr\nHdtagUHjkeZkdMMfnUGNv5aBNtFMqhcZH6EitEa9lGPkKBbJpoom3u8D8EHSIF1H5EZqqx9TLY5hWAIG\nPwJ4qwkpCGw5rCLVrjw7ARKukIFzNULANqjHUMcJ002TlUosJM4xJ4aAgckpLVGOGuPDhGAAexEcQmbg\nUsZdmqQrtuVUyyLteLbLbqtR6CTlcAIwY3xyMCmPgyefE0FEUODBoxQtRUuYTL9RC5o1sYb2PvcxUQfb\niJFi2CAl99pAzcckU2qVCxniARslIxM5pmMRGsQX9ZzYAfZrbg6ce6S74I8UMlgRQ2QVyvUjKKOE6IrJ\nLng370emHfe5m6LZULD5YiZutkD5ipjL2Bz77DvTE5kNPUhuoKBcTJcUgytfXAKUTWOcRKNlq0GImrxM\nJfr7AWbLFFNKGLeTrVDBwpcokJCv0zcOKWe8fd2xkeXkZTdmM66IgM27cyYmtQ6YF26Kd0qrWJeVZJV9\n3fyLYYvKN5csbRY2BHoYE5ERARRW65IrpkXMf48OrCXMtDIP0Z7wxI9DiTeKKeH4uuguhCJnwzR3WxLA\nVU6eBJEd7ZjS6JA83w7decq8uDI7LGKjcz1FySp3B7fE9DkHRGXxbsL7Fjar6vW2mAv8CuvI20B6jctp\n2yLDs24sPfB3sSxrrlhbuT1m6DZqiN0dl6umKx7NGZhmOTVGr20jfcxhqPQwTJfd7kel4rvxip4BqkvT\n7STy8knJ2BXGyJeNgwo1PXUZRDVy0LCTsSF1RFuRZe8cktHl9lgw8ntdPn1pVFL0MwJkJfdXBNUp5gNv\n50FTkrpo1t6wq4CVbcfj2XOrOzvBUzNH26sXGABI1gGxCdp2jEZrHgqQaWIaTJVTuguZhxqDvdYsrwFW\nYN58uuNcKHIrGdRSigyZInwQDYk0pjcqdSeU0WVU3Y9htzZBR7XRaCJr5YTZvq7fwermb5tuwb37lPLq\nB2IGg0iftkVbXaSyfCwVaRbfLBb88so0QqpmJGirFu8FcDiXOV1zTr8yW9XLdYQuUjh43xrXLdgsuYff\nCagInUk1eU1aLjVZoJRsNmStmOEpAqlYMwTvx7w6j2f421Cxr5cNZBIVlAxlXN2QiDqJ9v3sHhHkTanc\nlQuH8ptUyX8qncpBuXXBn7cSez9N0EoxCBl1GHUagbjstgJo4gzLvTmVIY6MiWYOBitzNUHfyqKwtKUr\nVoSCdZcGeA9lHUPA7PUprRRaT3m1hGKPyshtVS2ikG48w3oVerln1N1qGdtz46gZCrndw3LZ1B362RfW\nzDPuXbpsyLsRMTt1Rz1oKHRXp3iE41hkhQH6pxlvyCW2INnHt5XU8zRamOB3oW0udOhMpQFDjRkOcy06\nb4t0QTHvoRqmBna3WXzIMZyeK3GChF5eF8oDXRbjhk7BB6YKCgqwWUzEJ5K47HMSlhFkBUjaPRjdGM0z\nzOMwhW6b1NvSwP7XM1P5yi1oPvOspts1vr29SXqrMMrBhVogeodWyd69NqrO4jkyBxKmlXifoTowpfiY\n2cUCE0XMZqxUN39LCP09JqZifaEcBEo3mgtm1tWu5QR2GNq7UyQf4RIPSDOpDCAtwoPhRgdT1lJdcj4U\nlnH0wrJ8Uwu7c08L7ErnIrDATqCrOjpSbzGP1xHENABYONC4TknFPrJ8pe40A8fzGT0qBw9mAM1SKcHO\nfoiLcMC9AjHTqJzDG3xplSLPG9or2rMeq7Fzp9r0y7uJRMxgg51EbjfvYlH466A3ggvL2WQlDXjJqPW3\nBJGWAWDNN9LK8f46bADKPxakpkx23S9O47rGSXfDhVSIZsDympxWX1UOzWwMZRHkofVeKqizgbKkGgUT\nWykE9gRoRAOd9wfHZDYKa9i0LaPDiaUMvnU1gdBIqIoiVsdJ9swX47oxvMtOxtcS0zlD6llDkBuIiU5g\nPwRCYmtkkb25c8iRJXwGFPjI1wJ34I1z1ENicPdosPiUe9ZC2jnXIKzEdv01x2ER7DNDF3yxOwOhxNxI\nGqsmC92j25UQQFu9ZstOZ28AoCkuOYs0Uycm5u8jR1T39dMBwrko09rC65ENLnsxM8oebmyFCPiGJ1ED\n5Xqc9qZ237f1OnETAoEOwqUSvrdPTv56U7hV91EMTyC812MLQpr2710E3VVpsUCUMNhIxdt7UXZ1UNFb\njgzpZLXnf4DHrv6B7kq6UI50KMxcw1HZE2GpODfUTzNFLaqdrvzxKe5eUWdcojBaRbD4fFdVYJTElYDH\nNNVh6ofkoeWcs9CWGFmSBe0T4K8phFeygQg0prKMELNEy6qENzVtG9ZDcqj3a7L6ZLtvq50anWp7fAVu\nfwz55g4iM2Z2fA0pnwHDL7tt67zTxGITvsnJsZSpeq1EQsZcwtkBV9liu7Rl7jiVT1IIRtchB8TsTiaA\nwVHIQQ9RIOTiPQdKNqi1kC9iGlUqWK93gblNWlBw1eYB9Wk8FQogutwTf0caNMx8D4nPbANcmOOlskIy\nzALh15OlTrWnhP95rf08AN2J026zDE2DUF9k0eCevYBQIDjqKNW4XCZnjbHoIcKzbY5VzPbMs3ZyMz8K\nSucBmgPg6wrSK5ykbkapS5vuqvXc9GbjQJ8bPNzoxoWGyjbZvDs2OBrIqBmcQb2DLJ8v38McQ4mC4UsS\njf4PyfSCtpk274QZjvLCZbLiCBxQegk7jUU0NmTFJAcYCxd9xMWdlFkiszcltT2YzwuFFz7iA6aa4n5L\nHpBNfUA01GcAi1aCMYhmooS4zSlYcSOZkovMz36U3Fd9WtqIEOJLi7HMgHQDgNMdK6DTzAdHQtxerxVF\nHJnPrfNVG7270r3bp0bPnLNYLhObbAn6zqSAUeLtI2Y4KJDjBKCAh2vvYGbu0e2REYJWRj7MkGevsSSy\nb1kCXLt6tKGWAb7lt5c0xyJgUIJW7pdtnwgT0ZCa24BecCAwNnG5U2EwQbcjZGsFxqNGfaemd3oFEhES\nBaE0Fxms9UKTnMafu8wvZ2xymMrUduuRzOjDeX7oD5YsLC88V8CGMLxbbxIpt94KGykbr6e7L0R4oZl1\ntKMgFwQ2p9Txdbp0Y293LcsJymKizqI0F2xEp7y4SmWOJqHZtsbz80wVV9nv41CvtfxuSoGZJ5cNB7pI\nBgzNcQCeH3Jt0RaGGwboxxpuFbzilmkMFXxJm87tD4WNgu01nHfGCKeQcySEBZpVfJgi6sDFJ8uWnvKm\n9mPLHurtWzEfKqUEa1iC71bXjw5wrvhv9BYW8JSUELHmDquftQyKdq0DZXhULMHGQLf4e95WIaoA14LL\nbThz77kuhKULPTu2MNrBUKGorurhGugo5gs4ZUezSsUOe3KxYdrFMdGgny1GgTxMSMTp2RAZytKjv4kQ\nVx7XgzvpQLIbDjUPAkJv6lScwIRq1W3Ne0Rh0V6Bmn6U5uIuWnJjULmbaQiSODj3z0mAZvak0mSWIGwT\nTX83HztcC4W7e1f6a1thmcc5K61Icehla2hBELWPpixTkyC4eEVmk9Rq0m0ZXtx0JX2ZQXqXDEyePyMe\nJ70sdSzXk72zusqhY4yuOMGgbYNHqxOToK6NxujR7e4dV3Wk5JnSUthym8scjcPeCiKDNY4cHfTMnDXJ\n9zLVy01LtNKYpJ1s8FxVxigmxQNKEbIamxhx6yqwGC4aiISVOOUEjvNOdaUfXfUsE6jEwtwxyGxjlRK1\ncLyxXttq4QWN6PehgHv7jXykzPjInbEysebFvvPOOMdunmJvcCNMSvjUda8fL6xfGo0FDrLg8XZipd6S\noPVdYtyIM1Dg40KbBA3JuumPYtXuJaHrZnjZmdnM5OVo4ZNxktfCVT0c6bnD4bAeyn4bYt1ZPaX6hQHh\nJtvNYfpD0ONYlmqKuToQAMlz52Fh6bj45EbX89L5eLlSpWeyBlGotzriB0EPlclrGi5l2B5oPb1aB1ag\nyyYuu44l0F1oOVYnBIZsxIsHVITxi9lEuVPFkWASOUNuVQXfM4n5hxWR9qtuKnIcPsvbJsv1U10XlKh3\nKisqPhHU15xrCLr5gwFxPUKiNTLUBrkzgBOHXPVsHcLCiSD0YU56TRGfvEom43TWUKPPfl9Z54tgVQuT\njCRlaljAzeniQIcbbHZnn3f0HxbDG3DFYqWSxNrXabHhRsIOhhUHSPENyhGSTVO5t0XX5CdMspJPCd02\n3Oqv32ccbUK4O3YH6LEvp0WO3kSl5n50odVkI9B0i0iq4UPFGMkM8bEQJbgJoOH71P10vtdevJFQE4g2\nyhimiM53ZJRWgSZveHtENZc0Gjo0F9eioak9BnPpY1QxAFPC817svuhEstcU69bLCA4D1rO5R8AuIIBq\nyQJcifFLvbpAEYTLKJqysZrU8EEl3TSdC13A9hZvk4NC8VGEDAxcNrKw313dZp17kZPO5HSd1y6sljAW\nA9M1d6FMYV5SlBWf3WZNCUPS7qKNlda2YBsC6IUVB363f5RLGQOQHwbaijBSRCkrVoRxBHtc0Bd5J9V9\nP5uMTXkpZOxRcCQvImGgcmGuxxLb5zTqfS2xu7v3Sf3IIesSt9tVzcEcdbEvLGVJkLk4mb3G30DbIbri\nPZ09JkweDvMaQ3bxT2nfkz3Ilihkw9jqikkCCCz7E8h6z6KbhQErEW9VzJZzMCgJsyPjFam6iNwpe07S\nhyOvNVw2t9wpzL5xM11DvVzQwDaWEytNRHzDBs4KwEtpI2IpjUyVZHSwA0UGqqkzoCgrJFlNOvPlXqcS\nIcREouUIBmuttkrhPWJtSxOOgpsdvBR3kTOzAXNzSKxoaBAb0c5SDMUc6FIyGA8x5wg5DkUgjFUUodEt\nOYaB2VHVePW9mxHeBTdKWLzJow4ZZvjnoBuVigXljKCNh137ckV2y3Yg3Xi4UzJEI2V5Rw9AfnMs7xUw\nVHOFCg189maD3bmZAe7b4eaGZhyy4HVKjqCXmIH7vsEjRvbnfB0SQxxpuqBDJbHNCtW4vM643ZQQBVPP\na7oXSQIq9w2dHp0A7dtkocCZdQp9FKR9XdJAFIbVSHzIF1ZogeZlc0pXuNE0tagvD57xwDRFkAuoQyMu\nYDdZasXrpSmEE5UjHVkyYsISn8QsfXurzDybX468aoRoks654jjmRY5zi1oB8TcMdC2c3sicNaqfeuhd\nH1nPX7l4RpdqWMR7gGx9slXtG8S3KxpOi4qCD7yg3saD66nun4dzksQURoTUdXyrJR5UpHsfIlTF1aJa\nMdXyQtQnrkl00TeghQd00rRFZsCnhi0qrCSKiBfB2EVrd9RPpbgwJGZHuIQecdBmNetc2ylSEClqVBPR\nGOPPIxrnswEZjmnS0jxKW9VSM1QVxSPJnPFswCqT95SoKD6CP4xdX28WIUGiNaIKodXXJHEIsXBCxLsr\nPwWPCtoplC6hhpKmW5dQo92iCTyY2KioKzO8XR6FKm6qonMKVEwQNtlYE9c97KMtEnp25VOdMP46SQXS\nYsSVp7vm8LP87VYI8SOKcW3s2oedYFtt45rvDzoTF0GmS6wELQ9uo98HhjQAI1Dt91cgjJOwygNmLoZE\nX5K2zQiNA163uMCl5xzaBqY4YTL0wgALg3IFdYSp0RFYLWdt6IxoGI1tnoxcjlUEPo5eGIc3mS3SmaLn\nOdumfUQQ4Jgmgaa5anUVQsfBDrlAN5oaX7O0JO71SSPSWiHBsT9WIPy2J1Cace9ZZLRxblFPSXcvsuHh\nhvnhWQltEDAe7MgvkFQ8lGVFa8jhzijoF9kLmMhMILSzYnfXnZPNP7TlAAwlLHK1RqlpHskJqb6CPpGP\nQvOAhEMsM3zJ2KejZx0esxkjxA0ZufVvGAMN3vTUMplQaF4RiQkp9fzBXf3CMk01dWjOMMIEXTeKzIQe\nEcffzjixWU9FpAyGp2rVl4ETRgqljOGw4UgK31r0ZIEGnH0xGz1FtbW1OcQM008JVujRqulCucEMmntr\n" + } + ), + "method": "POST", + "uri": "/requestcompression/putcontentwithencoding", + "headers": MappingProxyType({"Content-Encoding": "gzip"}), + } + ), + MappingProxyType( + { + "id": "SDKAppendedGzipAfterProvidedEncoding_restJson1", + "documentation": "Compression algorithm encoding is appended to the Content-Encoding header, and the\nuser-provided content-encoding is in the Content-Encoding header before the\nrequest compression encoding from the HTTP binding.\n", + "protocol": "aws.protocols#restJson1", + "params": MappingProxyType( + { + "encoding": "custom", + "data": "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\n", + } + ), + "method": "POST", + "uri": "/requestcompression/putcontentwithencoding", + "headers": MappingProxyType( + {"Content-Encoding": "custom, gzip"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#requestCompression"), + value=MappingProxyType({"encodings": ("gzip",)}), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "POST", "uri": "/requestcompression/putcontentwithencoding"} + ), + ), + ], +) + +QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#QueryIdempotencyTokenAutoFillInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "token": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#idempotencyToken")), + Trait.new(id=ShapeID("smithy.api#httpQuery"), value="token"), + ], + } + }, +) + +QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#QueryIdempotencyTokenAutoFillOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL = Schema( + id=ShapeID("aws.protocoltests.restjson#QueryIdempotencyTokenAutoFill"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonQueryIdempotencyTokenAutoFill", + "documentation": "Automatically adds idempotency token when not set", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/QueryIdempotencyTokenAutoFill", + "body": "", + "queryParams": ("token=00000000-0000-4000-8000-000000000000",), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonQueryIdempotencyTokenAutoFillIsSet", + "documentation": "Uses the given idempotency token as-is", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/QueryIdempotencyTokenAutoFill", + "body": "", + "queryParams": ("token=00000000-0000-4000-8000-000000000000",), + "params": MappingProxyType( + {"token": "00000000-0000-4000-8000-000000000000"} + ), + "appliesTo": "client", + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#tags"), value=("client-only",)), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/QueryIdempotencyTokenAutoFill", "method": "POST"} + ), + ), + ], +) + +QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#QueryParamsAsStringListMapInput"), + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("HttpQueryParamsTrait",)), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "qux": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="corge")], + }, + "foo": { + "target": STRING_LIST_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQueryParams"))], + }, + }, +) + +QUERY_PARAMS_AS_STRING_LIST_MAP_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#QueryParamsAsStringListMapOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +QUERY_PARAMS_AS_STRING_LIST_MAP = Schema( + id=ShapeID("aws.protocoltests.restjson#QueryParamsAsStringListMap"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonQueryParamsStringListMap", + "documentation": "Serialize query params from map of list strings", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/StringListMap", + "body": "", + "queryParams": ("corge=named", "baz=bar", "baz=qux"), + "params": MappingProxyType( + { + "qux": "named", + "foo": MappingProxyType({"baz": ("bar", "qux")}), + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonServersQueryParamsStringListMap", + "documentation": "Servers put all query params in map", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/StringListMap", + "body": "", + "queryParams": ("corge=named", "baz=bar", "baz=qux"), + "params": MappingProxyType( + { + "qux": "named", + "foo": MappingProxyType( + {"corge": ("named",), "baz": ("bar", "qux")} + ), + } + ), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/StringListMap", "method": "POST"}), + ), + ], +) + +QUERY_PRECEDENCE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#QueryPrecedenceInput"), + traits=[ + Trait.new(id=ShapeID("smithy.api#suppress"), value=("HttpQueryParamsTrait",)), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQuery"), value="bar")], + }, + "baz": { + "target": STRING_MAP, + "traits": [Trait.new(id=ShapeID("smithy.api#httpQueryParams"))], + }, + }, +) + +QUERY_PRECEDENCE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#QueryPrecedenceOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +QUERY_PRECEDENCE = Schema( + id=ShapeID("aws.protocoltests.restjson#QueryPrecedence"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonQueryPrecedence", + "documentation": "Prefer named query parameters when serializing", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/Precedence", + "body": "", + "queryParams": ("bar=named", "qux=alsoFromMap"), + "params": MappingProxyType( + { + "foo": "named", + "baz": MappingProxyType( + {"bar": "fromMap", "qux": "alsoFromMap"} + ), + } + ), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonServersPutAllQueryParamsInMap", + "documentation": "Servers put all query params in map", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/Precedence", + "body": "", + "queryParams": ("bar=named", "qux=fromMap"), + "params": MappingProxyType( + { + "foo": "named", + "baz": MappingProxyType( + {"bar": "named", "qux": "fromMap"} + ), + } + ), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/Precedence", "method": "POST"}), + ), + ], +) + +RESPONSE_CODE_HTTP_FALLBACK_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ResponseCodeHttpFallbackInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#ResponseCodeHttpFallbackInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +RESPONSE_CODE_HTTP_FALLBACK_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ResponseCodeHttpFallbackOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#ResponseCodeHttpFallbackInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +RESPONSE_CODE_HTTP_FALLBACK = Schema( + id=ShapeID("aws.protocoltests.restjson#ResponseCodeHttpFallback"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpResponseCodeNotSetFallsBackToHttpCode", + "documentation": "This test ensures that servers fall back to the code set\nby @http if @httpResponseCode is not set.", + "protocol": "aws.protocols#restJson1", + "code": 201, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": "{}", + "bodyMediaType": "application/json", + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "GET", "uri": "/responseCodeHttpFallback", "code": 201} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +RESPONSE_CODE_REQUIRED_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ResponseCodeRequiredInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +RESPONSE_CODE_REQUIRED_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#ResponseCodeRequiredOutput"), + traits=[Trait.new(id=ShapeID("smithy.api#output"))], + members={ + "responseCode": { + "target": INTEGER, + "traits": [ + Trait.new(id=ShapeID("smithy.api#required")), + Trait.new(id=ShapeID("smithy.api#httpResponseCode")), + ], + } + }, +) + +RESPONSE_CODE_REQUIRED = Schema( + id=ShapeID("aws.protocoltests.restjson#ResponseCodeRequired"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpResponseCodeRequired", + "documentation": "This test ensures that servers handle @httpResponseCode being @required.", + "protocol": "aws.protocols#restJson1", + "code": 201, + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "body": "{}", + "bodyMediaType": "application/json", + "params": MappingProxyType({"responseCode": 201}), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"method": "GET", "uri": "/responseCodeRequired", "code": 200} + ), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +SIMPLE_SCALAR_PROPERTIES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SimpleScalarPropertiesInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#SimpleScalarPropertiesInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "stringValue": {"target": STRING}, + "trueBooleanValue": {"target": BOOLEAN}, + "falseBooleanValue": {"target": BOOLEAN}, + "byteValue": {"target": BYTE}, + "shortValue": {"target": SHORT}, + "integerValue": {"target": INTEGER}, + "longValue": {"target": LONG}, + "floatValue": {"target": FLOAT}, + "doubleValue": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#jsonName"), value="DoubleDribble") + ], + }, + }, +) + +SIMPLE_SCALAR_PROPERTIES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SimpleScalarPropertiesOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#SimpleScalarPropertiesInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "stringValue": {"target": STRING}, + "trueBooleanValue": {"target": BOOLEAN}, + "falseBooleanValue": {"target": BOOLEAN}, + "byteValue": {"target": BYTE}, + "shortValue": {"target": SHORT}, + "integerValue": {"target": INTEGER}, + "longValue": {"target": LONG}, + "floatValue": {"target": FLOAT}, + "doubleValue": { + "target": DOUBLE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#jsonName"), value="DoubleDribble") + ], + }, + }, +) + +SIMPLE_SCALAR_PROPERTIES = Schema( + id=ShapeID("aws.protocoltests.restjson#SimpleScalarProperties"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonSimpleScalarProperties", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": '{\n "stringValue": "string",\n "trueBooleanValue": true,\n "falseBooleanValue": false,\n "byteValue": 1,\n "shortValue": 2,\n "integerValue": 3,\n "longValue": 4,\n "floatValue": 5.5,\n "DoubleDribble": 6.5\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json", "X-Foo": "Foo"} + ), + "params": MappingProxyType( + { + "foo": "Foo", + "stringValue": "string", + "trueBooleanValue": True, + "falseBooleanValue": False, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5, + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDoesntSerializeNullStructureValues", + "documentation": "Rest Json should not serialize null structure values", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"stringValue": None}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonServersDontSerializeNullStructureValues", + "documentation": "Rest Json should not deserialize null structure values", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": '{\n "stringValue": null\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({}), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNaNFloatInputs", + "documentation": "Supports handling NaN float values.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": '{\n "floatValue": "NaN",\n "DoubleDribble": "NaN"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"floatValue": "NaN", "doubleValue": "NaN"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsInfinityFloatInputs", + "documentation": "Supports handling Infinity float values.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": '{\n "floatValue": "Infinity",\n "DoubleDribble": "Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"floatValue": "Infinity", "doubleValue": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNegativeInfinityFloatInputs", + "documentation": "Supports handling -Infinity float values.", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/SimpleScalarProperties", + "body": '{\n "floatValue": "-Infinity",\n "DoubleDribble": "-Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"floatValue": "-Infinity", "doubleValue": "-Infinity"} + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonSimpleScalarProperties", + "documentation": "Serializes simple scalar properties", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "stringValue": "string",\n "trueBooleanValue": true,\n "falseBooleanValue": false,\n "byteValue": 1,\n "shortValue": 2,\n "integerValue": 3,\n "longValue": 4,\n "floatValue": 5.5,\n "DoubleDribble": 6.5\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json", "X-Foo": "Foo"} + ), + "params": MappingProxyType( + { + "foo": "Foo", + "stringValue": "string", + "trueBooleanValue": True, + "falseBooleanValue": False, + "byteValue": 1, + "shortValue": 2, + "integerValue": 3, + "longValue": 4, + "floatValue": 5.5, + "doubleValue": 6.5, + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDoesntDeserializeNullStructureValues", + "documentation": "Rest Json should not deserialize null structure values", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "stringValue": null\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({}), + "appliesTo": "client", + } + ), + MappingProxyType( + { + "id": "RestJsonServersDontSerializeNullStructureValues", + "documentation": "Rest Json should not serialize null structure values", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType({"stringValue": None}), + "appliesTo": "server", + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNaNFloatInputs", + "documentation": "Supports handling NaN float values.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "floatValue": "NaN",\n "DoubleDribble": "NaN"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"floatValue": "NaN", "doubleValue": "NaN"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsInfinityFloatInputs", + "documentation": "Supports handling Infinity float values.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "floatValue": "Infinity",\n "DoubleDribble": "Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"floatValue": "Infinity", "doubleValue": "Infinity"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSupportsNegativeInfinityFloatInputs", + "documentation": "Supports handling -Infinity float values.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "floatValue": "-Infinity",\n "DoubleDribble": "-Infinity"\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + {"floatValue": "-Infinity", "doubleValue": "-Infinity"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/SimpleScalarProperties", "method": "PUT"}), + ), + ], +) + +SPARSE_SHORT_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#SparseShortList"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#sparse"))], + members={"member": {"target": SHORT}}, +) + +SPARSE_STRING_LIST = Schema.collection( + id=ShapeID("aws.protocoltests.shared#SparseStringList"), + shape_type=ShapeType.LIST, + traits=[Trait.new(id=ShapeID("smithy.api#sparse"))], + members={"member": {"target": STRING}}, +) + +SPARSE_JSON_LISTS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SparseJsonListsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#SparseJsonListsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "sparseStringList": {"target": SPARSE_STRING_LIST}, + "sparseShortList": {"target": SPARSE_SHORT_LIST}, + }, +) + +SPARSE_JSON_LISTS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SparseJsonListsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#SparseJsonListsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "sparseStringList": {"target": SPARSE_STRING_LIST}, + "sparseShortList": {"target": SPARSE_SHORT_LIST}, + }, +) + +SPARSE_JSON_LISTS = Schema( + id=ShapeID("aws.protocoltests.restjson#SparseJsonLists"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonSparseListsSerializeNull", + "documentation": "Serializes null values in sparse lists", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/SparseJsonLists", + "body": '{\n "sparseStringList": [\n null,\n "hi"\n ],\n "sparseShortList": [\n null,\n 2\n ]\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseStringList": (None, "hi"), + "sparseShortList": (None, 2), + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonSparseListsSerializeNull", + "documentation": "Serializes null values in sparse lists", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "sparseStringList": [\n null,\n "hi"\n ],\n "sparseShortList": [\n null,\n 2\n ]\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseStringList": (None, "hi"), + "sparseShortList": (None, 2), + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/SparseJsonLists", "method": "PUT"}), + ), + ], +) + +SPARSE_BOOLEAN_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SparseBooleanMap"), + shape_type=ShapeType.MAP, + traits=[Trait.new(id=ShapeID("smithy.api#sparse"))], + members={"key": {"target": STRING}, "value": {"target": BOOLEAN}}, +) + +SPARSE_NUMBER_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SparseNumberMap"), + shape_type=ShapeType.MAP, + traits=[Trait.new(id=ShapeID("smithy.api#sparse"))], + members={"key": {"target": STRING}, "value": {"target": INTEGER}}, +) + +SPARSE_SET_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SparseSetMap"), + shape_type=ShapeType.MAP, + traits=[Trait.new(id=ShapeID("smithy.api#sparse"))], + members={"key": {"target": STRING}, "value": {"target": STRING_SET}}, +) + +SPARSE_STRING_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.shared#SparseStringMap"), + shape_type=ShapeType.MAP, + traits=[Trait.new(id=ShapeID("smithy.api#sparse"))], + members={"key": {"target": STRING}, "value": {"target": STRING}}, +) + +SPARSE_STRUCT_MAP = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SparseStructMap"), + shape_type=ShapeType.MAP, + traits=[Trait.new(id=ShapeID("smithy.api#sparse"))], + members={"key": {"target": STRING}, "value": {"target": GREETING_STRUCT}}, +) + +SPARSE_JSON_MAPS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SparseJsonMapsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#SparseJsonMapsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "sparseStructMap": {"target": SPARSE_STRUCT_MAP}, + "sparseNumberMap": {"target": SPARSE_NUMBER_MAP}, + "sparseBooleanMap": {"target": SPARSE_BOOLEAN_MAP}, + "sparseStringMap": {"target": SPARSE_STRING_MAP}, + "sparseSetMap": {"target": SPARSE_SET_MAP}, + }, +) + +SPARSE_JSON_MAPS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#SparseJsonMapsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#SparseJsonMapsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "sparseStructMap": {"target": SPARSE_STRUCT_MAP}, + "sparseNumberMap": {"target": SPARSE_NUMBER_MAP}, + "sparseBooleanMap": {"target": SPARSE_BOOLEAN_MAP}, + "sparseStringMap": {"target": SPARSE_STRING_MAP}, + "sparseSetMap": {"target": SPARSE_SET_MAP}, + }, +) + +SPARSE_JSON_MAPS = Schema( + id=ShapeID("aws.protocoltests.restjson#SparseJsonMaps"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonSparseJsonMaps", + "documentation": "Serializes JSON maps", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/SparseJsonMaps", + "body": '{\n "sparseStructMap": {\n "foo": {\n "hi": "there"\n },\n "baz": {\n "hi": "bye"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseStructMap": MappingProxyType( + { + "foo": MappingProxyType({"hi": "there"}), + "baz": MappingProxyType({"hi": "bye"}), + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializesSparseNullMapValues", + "documentation": "Serializes JSON map values in sparse maps", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/SparseJsonMaps", + "body": '{\n "sparseBooleanMap": {\n "x": null\n },\n "sparseNumberMap": {\n "x": null\n },\n "sparseStringMap": {\n "x": null\n },\n "sparseStructMap": {\n "x": null\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseBooleanMap": MappingProxyType({"x": None}), + "sparseNumberMap": MappingProxyType({"x": None}), + "sparseStringMap": MappingProxyType({"x": None}), + "sparseStructMap": MappingProxyType({"x": None}), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializesZeroValuesInSparseMaps", + "documentation": "Ensure that 0 and false are sent over the wire in all maps and lists", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/SparseJsonMaps", + "body": '{\n "sparseNumberMap": {\n "x": 0\n },\n "sparseBooleanMap": {\n "x": false\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseNumberMap": MappingProxyType({"x": 0}), + "sparseBooleanMap": MappingProxyType({"x": False}), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializesSparseSetMap", + "documentation": "A request that contains a sparse map of sets", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/SparseJsonMaps", + "body": '{\n "sparseSetMap": {\n "x": [],\n "y": ["a", "b"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseSetMap": MappingProxyType( + {"x": (), "y": ("a", "b")} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonSerializesSparseSetMapAndRetainsNull", + "documentation": "A request that contains a sparse map of sets.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/SparseJsonMaps", + "body": '{\n "sparseSetMap": {\n "x": [],\n "y": ["a", "b"],\n "z": null\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseSetMap": MappingProxyType( + {"x": (), "y": ("a", "b"), "z": None} + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonSparseJsonMaps", + "documentation": "Deserializes JSON maps", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "sparseStructMap": {\n "foo": {\n "hi": "there"\n },\n "baz": {\n "hi": "bye"\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseStructMap": MappingProxyType( + { + "foo": MappingProxyType({"hi": "there"}), + "baz": MappingProxyType({"hi": "bye"}), + } + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializesSparseNullMapValues", + "documentation": "Deserializes null JSON map values", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "sparseBooleanMap": {\n "x": null\n },\n "sparseNumberMap": {\n "x": null\n },\n "sparseStringMap": {\n "x": null\n },\n "sparseStructMap": {\n "x": null\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseBooleanMap": MappingProxyType({"x": None}), + "sparseNumberMap": MappingProxyType({"x": None}), + "sparseStringMap": MappingProxyType({"x": None}), + "sparseStructMap": MappingProxyType({"x": None}), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializesZeroValuesInSparseMaps", + "documentation": "Ensure that 0 and false are sent over the wire in all maps and lists", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "sparseNumberMap": {\n "x": 0\n },\n "sparseBooleanMap": {\n "x": false\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseNumberMap": MappingProxyType({"x": 0}), + "sparseBooleanMap": MappingProxyType({"x": False}), + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializesSparseSetMap", + "documentation": "A response that contains a sparse map of sets", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "sparseSetMap": {\n "x": [],\n "y": ["a", "b"]\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseSetMap": MappingProxyType( + {"x": (), "y": ("a", "b")} + ) + } + ), + } + ), + MappingProxyType( + { + "id": "RestJsonDeserializesSparseSetMapAndRetainsNull", + "documentation": "A response that contains a sparse map of sets.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "sparseSetMap": {\n "x": [],\n "y": ["a", "b"],\n "z": null\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "sparseSetMap": MappingProxyType( + {"x": (), "y": ("a", "b"), "z": None} + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/SparseJsonMaps", "method": "POST"}), + ), + ], +) + +STREAMING_BLOB = Schema( + id=ShapeID("aws.protocoltests.restjson#StreamingBlob"), + shape_type=ShapeType.BLOB, + traits=[Trait.new(id=ShapeID("smithy.api#streaming"))], +) + +STREAMING_TRAITS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StreamingTraitsInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#StreamingTraitsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "blob": { + "target": STREAMING_BLOB, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=""), + Trait.new(id=ShapeID("smithy.api#httpPayload")), + ], + }, + }, +) + +STREAMING_TRAITS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StreamingTraitsOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#StreamingTraitsInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "blob": { + "target": STREAMING_BLOB, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=""), + Trait.new(id=ShapeID("smithy.api#httpPayload")), + ], + }, + }, +) + +STREAMING_TRAITS = Schema( + id=ShapeID("aws.protocoltests.restjson#StreamingTraits"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonStreamingTraitsWithBlob", + "documentation": "Serializes a blob in the HTTP payload", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/StreamingTraits", + "body": "blobby blob blob", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"X-Foo": "Foo", "Content-Type": "application/octet-stream"} + ), + "params": MappingProxyType( + {"foo": "Foo", "blob": "blobby blob blob"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonStreamingTraitsWithNoBlobBody", + "documentation": "Serializes an empty blob in the HTTP payload", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/StreamingTraits", + "body": "", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType({"X-Foo": "Foo"}), + "params": MappingProxyType({"foo": "Foo"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonStreamingTraitsWithBlob", + "documentation": "Serializes a blob in the HTTP payload", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "blobby blob blob", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"X-Foo": "Foo", "Content-Type": "application/octet-stream"} + ), + "params": MappingProxyType( + {"foo": "Foo", "blob": "blobby blob blob"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonStreamingTraitsWithNoBlobBody", + "documentation": "Serializes an empty blob in the HTTP payload", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType({"X-Foo": "Foo"}), + "params": MappingProxyType({"foo": "Foo"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/StreamingTraits", "method": "POST"}), + ), + ], +) + +STREAMING_TRAITS_REQUIRE_LENGTH_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StreamingTraitsRequireLengthInput"), + traits=[Trait.new(id=ShapeID("smithy.api#input"))], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "blob": { + "target": FINITE_STREAMING_BLOB, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=""), + Trait.new(id=ShapeID("smithy.api#httpPayload")), + ], + }, + }, +) + +STREAMING_TRAITS_REQUIRE_LENGTH_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StreamingTraitsRequireLengthOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +STREAMING_TRAITS_REQUIRE_LENGTH = Schema( + id=ShapeID("aws.protocoltests.restjson#StreamingTraitsRequireLength"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonStreamingTraitsRequireLengthWithBlob", + "documentation": "Serializes a blob in the HTTP payload with a required length", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/StreamingTraitsRequireLength", + "body": "blobby blob blob", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"X-Foo": "Foo", "Content-Type": "application/octet-stream"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"foo": "Foo", "blob": "blobby blob blob"} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonStreamingTraitsRequireLengthWithNoBlobBody", + "documentation": "Serializes an empty blob in the HTTP payload", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/StreamingTraitsRequireLength", + "body": "", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType({"X-Foo": "Foo"}), + "params": MappingProxyType({"foo": "Foo"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/StreamingTraitsRequireLength", "method": "POST"} + ), + ), + ], +) + +STREAMING_TEXT_PLAIN_BLOB = Schema( + id=ShapeID("aws.protocoltests.restjson#StreamingTextPlainBlob"), + shape_type=ShapeType.BLOB, + traits=[ + Trait.new(id=ShapeID("smithy.api#streaming")), + Trait.new(id=ShapeID("smithy.api#mediaType"), value="text/plain"), + ], +) + +STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StreamingTraitsWithMediaTypeInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#StreamingTraitsWithMediaTypeInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "blob": { + "target": STREAMING_TEXT_PLAIN_BLOB, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=""), + Trait.new(id=ShapeID("smithy.api#httpPayload")), + ], + }, + }, +) + +STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#StreamingTraitsWithMediaTypeOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#StreamingTraitsWithMediaTypeInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "foo": { + "target": STRING, + "traits": [Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Foo")], + }, + "blob": { + "target": STREAMING_TEXT_PLAIN_BLOB, + "traits": [ + Trait.new(id=ShapeID("smithy.api#default"), value=""), + Trait.new(id=ShapeID("smithy.api#httpPayload")), + ], + }, + }, +) + +STREAMING_TRAITS_WITH_MEDIA_TYPE = Schema( + id=ShapeID("aws.protocoltests.restjson#StreamingTraitsWithMediaType"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonStreamingTraitsWithMediaTypeWithBlob", + "documentation": "Serializes a blob in the HTTP payload with a content-type", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/StreamingTraitsWithMediaType", + "body": "blobby blob blob", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"X-Foo": "Foo", "Content-Type": "text/plain"} + ), + "params": MappingProxyType( + {"foo": "Foo", "blob": "blobby blob blob"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonStreamingTraitsWithMediaTypeWithBlob", + "documentation": "Serializes a blob in the HTTP payload with a content-type", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "blobby blob blob", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType( + {"X-Foo": "Foo", "Content-Type": "text/plain"} + ), + "params": MappingProxyType( + {"foo": "Foo", "blob": "blobby blob blob"} + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/StreamingTraitsWithMediaType", "method": "POST"} + ), + ), + ], +) + +TEST_CONFIG = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestConfig"), + members={"timeout": {"target": INTEGER}}, +) + +TEST_BODY_STRUCTURE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestBodyStructureInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestBodyStructureInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="x-amz-test-id") + ], + }, + "testConfig": {"target": TEST_CONFIG}, + }, +) + +TEST_BODY_STRUCTURE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestBodyStructureOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestBodyStructureInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="x-amz-test-id") + ], + }, + "testConfig": {"target": TEST_CONFIG}, + }, +) + +TEST_BODY_STRUCTURE = Schema( + id=ShapeID("aws.protocoltests.restjson#TestBodyStructure"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonTestBodyStructure", + "documentation": "Serializes a structure", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/body", + "body": '{"testConfig":\n {"timeout": 10}\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"testConfig": MappingProxyType({"timeout": 10})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpWithEmptyBody", + "documentation": "Serializes an empty structure in the body", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/body", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({}), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/body", "method": "POST"}), + ), + ], +) + +TEST_GET_NO_INPUT_NO_PAYLOAD_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestGetNoInputNoPayloadInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +TEST_GET_NO_INPUT_NO_PAYLOAD_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestGetNoInputNoPayloadOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestNoPayloadInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Amz-Test-Id") + ], + } + }, +) + +TEST_GET_NO_INPUT_NO_PAYLOAD = Schema( + id=ShapeID("aws.protocoltests.restjson#TestGetNoInputNoPayload"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpGetWithNoInput", + "documentation": "Serializes a GET request for an operation with no input, and therefore no modeled body", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/no_input_no_payload", + "body": "", + "forbidHeaders": ("Content-Type", "Content-Length"), + "params": MappingProxyType({}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/no_input_no_payload", "method": "GET"}), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +TEST_GET_NO_PAYLOAD_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestGetNoPayloadInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestNoPayloadInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Amz-Test-Id") + ], + } + }, +) + +TEST_GET_NO_PAYLOAD_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestGetNoPayloadOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestNoPayloadInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Amz-Test-Id") + ], + } + }, +) + +TEST_GET_NO_PAYLOAD = Schema( + id=ShapeID("aws.protocoltests.restjson#TestGetNoPayload"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpGetWithNoModeledBody", + "documentation": "Serializes a GET request with no modeled body", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/no_payload", + "body": "", + "forbidHeaders": ("Content-Length", "Content-Type"), + "params": MappingProxyType({}), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpGetWithHeaderMemberNoModeledBody", + "documentation": "Serializes a GET request with header member but no modeled body", + "protocol": "aws.protocols#restJson1", + "method": "GET", + "uri": "/no_payload", + "body": "", + "headers": MappingProxyType({"X-Amz-Test-Id": "t-12345"}), + "forbidHeaders": ("Content-Length", "Content-Type"), + "params": MappingProxyType({"testId": "t-12345"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/no_payload", "method": "GET"}), + ), + Trait.new(id=ShapeID("smithy.api#readonly")), + ], +) + +TEST_PAYLOAD_BLOB_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestPayloadBlobInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestPayloadBlobInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "contentType": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="Content-Type") + ], + }, + "data": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +TEST_PAYLOAD_BLOB_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestPayloadBlobOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestPayloadBlobInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "contentType": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="Content-Type") + ], + }, + "data": { + "target": BLOB, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +TEST_PAYLOAD_BLOB = Schema( + id=ShapeID("aws.protocoltests.restjson#TestPayloadBlob"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpWithEmptyBlobPayload", + "documentation": "Serializes a payload targeting an empty blob", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/blob_payload", + "body": "", + "bodyMediaType": "application/octet-stream", + "headers": MappingProxyType({}), + "params": MappingProxyType({}), + } + ), + MappingProxyType( + { + "id": "RestJsonTestPayloadBlob", + "documentation": "Serializes a payload targeting a blob", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/blob_payload", + "body": "1234", + "bodyMediaType": "image/jpg", + "headers": MappingProxyType({"Content-Type": "image/jpg"}), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"contentType": "image/jpg", "data": "1234"} + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/blob_payload", "method": "POST"}), + ), + ], +) + +TEST_PAYLOAD_STRUCTURE_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestPayloadStructureInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestPayloadStructureInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="x-amz-test-id") + ], + }, + "payloadConfig": { + "target": PAYLOAD_CONFIG, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +TEST_PAYLOAD_STRUCTURE_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestPayloadStructureOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestPayloadStructureInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="x-amz-test-id") + ], + }, + "payloadConfig": { + "target": PAYLOAD_CONFIG, + "traits": [Trait.new(id=ShapeID("smithy.api#httpPayload"))], + }, + }, +) + +TEST_PAYLOAD_STRUCTURE = Schema( + id=ShapeID("aws.protocoltests.restjson#TestPayloadStructure"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpWithEmptyStructurePayload", + "documentation": "Serializes a payload targeting an empty structure", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/payload", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({}), + } + ), + MappingProxyType( + { + "id": "RestJsonTestPayloadStructure", + "documentation": "Serializes a payload targeting a structure", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/payload", + "body": '{"data": 25\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType( + {"payloadConfig": MappingProxyType({"data": 25})} + ), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpWithHeadersButNoPayload", + "documentation": "Serializes an request with header members but no payload", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/payload", + "body": "{}", + "bodyMediaType": "application/json", + "headers": MappingProxyType( + { + "Content-Type": "application/json", + "X-Amz-Test-Id": "t-12345", + } + ), + "requireHeaders": ("Content-Length",), + "params": MappingProxyType({"testId": "t-12345"}), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/payload", "method": "POST"}), + ), + ], +) + +TEST_POST_NO_INPUT_NO_PAYLOAD_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestPostNoInputNoPayloadInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +TEST_POST_NO_INPUT_NO_PAYLOAD_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestPostNoInputNoPayloadOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestNoPayloadInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Amz-Test-Id") + ], + } + }, +) + +TEST_POST_NO_INPUT_NO_PAYLOAD = Schema( + id=ShapeID("aws.protocoltests.restjson#TestPostNoInputNoPayload"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPostWithNoInput", + "documentation": "Serializes a POST request for an operation with no input, and therefore no modeled body", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/no_input_no_payload", + "body": "", + "forbidHeaders": ("Content-Type",), + "params": MappingProxyType({}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/no_input_no_payload", "method": "POST"}), + ), + ], +) + +TEST_POST_NO_PAYLOAD_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestPostNoPayloadInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestNoPayloadInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Amz-Test-Id") + ], + } + }, +) + +TEST_POST_NO_PAYLOAD_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TestPostNoPayloadOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TestNoPayloadInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "testId": { + "target": STRING, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-Amz-Test-Id") + ], + } + }, +) + +TEST_POST_NO_PAYLOAD = Schema( + id=ShapeID("aws.protocoltests.restjson#TestPostNoPayload"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonHttpPostWithNoModeledBody", + "documentation": "Serializes a POST request with no modeled body", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/no_payload", + "body": "", + "forbidHeaders": ("Content-Type",), + "params": MappingProxyType({}), + } + ), + MappingProxyType( + { + "id": "RestJsonHttpWithPostHeaderMemberNoModeledBody", + "documentation": "Serializes a POST request with header member but no modeled body", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/no_payload", + "body": "", + "headers": MappingProxyType({"X-Amz-Test-Id": "t-12345"}), + "forbidHeaders": ("Content-Type",), + "params": MappingProxyType({"testId": "t-12345"}), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/no_payload", "method": "POST"}), + ), + ], +) + +TIMESTAMP_FORMAT_HEADERS_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TimestampFormatHeadersInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TimestampFormatHeadersIO", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={ + "memberEpochSeconds": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ), + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-memberEpochSeconds" + ), + ], + }, + "memberHttpDate": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date"), + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-memberHttpDate" + ), + ], + }, + "memberDateTime": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time"), + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-memberDateTime" + ), + ], + }, + "defaultFormat": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-defaultFormat") + ], + }, + "targetEpochSeconds": { + "target": EPOCH_SECONDS, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-targetEpochSeconds" + ) + ], + }, + "targetHttpDate": { + "target": HTTP_DATE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-targetHttpDate") + ], + }, + "targetDateTime": { + "target": DATE_TIME, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-targetDateTime") + ], + }, + }, +) + +TIMESTAMP_FORMAT_HEADERS_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#TimestampFormatHeadersOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#TimestampFormatHeadersIO", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={ + "memberEpochSeconds": { + "target": TIMESTAMP, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#timestampFormat"), value="epoch-seconds" + ), + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-memberEpochSeconds" + ), + ], + }, + "memberHttpDate": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="http-date"), + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-memberHttpDate" + ), + ], + }, + "memberDateTime": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#timestampFormat"), value="date-time"), + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-memberDateTime" + ), + ], + }, + "defaultFormat": { + "target": TIMESTAMP, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-defaultFormat") + ], + }, + "targetEpochSeconds": { + "target": EPOCH_SECONDS, + "traits": [ + Trait.new( + id=ShapeID("smithy.api#httpHeader"), value="X-targetEpochSeconds" + ) + ], + }, + "targetHttpDate": { + "target": HTTP_DATE, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-targetHttpDate") + ], + }, + "targetDateTime": { + "target": DATE_TIME, + "traits": [ + Trait.new(id=ShapeID("smithy.api#httpHeader"), value="X-targetDateTime") + ], + }, + }, +) + +TIMESTAMP_FORMAT_HEADERS = Schema( + id=ShapeID("aws.protocoltests.restjson#TimestampFormatHeaders"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonTimestampFormatHeaders", + "documentation": "Tests how timestamp request headers are serialized", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/TimestampFormatHeaders", + "headers": MappingProxyType( + { + "X-memberEpochSeconds": "1576540098", + "X-memberHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-memberDateTime": "2019-12-16T23:48:18Z", + "X-defaultFormat": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetEpochSeconds": "1576540098", + "X-targetHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetDateTime": "2019-12-16T23:48:18Z", + } + ), + "body": "", + "params": MappingProxyType( + { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098, + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonTimestampFormatHeaders", + "documentation": "Tests how timestamp response headers are serialized", + "protocol": "aws.protocols#restJson1", + "code": 200, + "headers": MappingProxyType( + { + "X-memberEpochSeconds": "1576540098", + "X-memberHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-memberDateTime": "2019-12-16T23:48:18Z", + "X-defaultFormat": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetEpochSeconds": "1576540098", + "X-targetHttpDate": "Mon, 16 Dec 2019 23:48:18 GMT", + "X-targetDateTime": "2019-12-16T23:48:18Z", + } + ), + "params": MappingProxyType( + { + "memberEpochSeconds": 1576540098, + "memberHttpDate": 1576540098, + "memberDateTime": 1576540098, + "defaultFormat": 1576540098, + "targetEpochSeconds": 1576540098, + "targetHttpDate": 1576540098, + "targetDateTime": 1576540098, + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType( + {"uri": "/TimestampFormatHeaders", "method": "POST"} + ), + ), + ], +) + +UNIT_INPUT_AND_OUTPUT_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#UnitInputAndOutputInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], +) + +UNIT_INPUT_AND_OUTPUT_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#UnitInputAndOutputOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), value="smithy.api#Unit" + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], +) + +UNIT_INPUT_AND_OUTPUT = Schema( + id=ShapeID("aws.protocoltests.restjson#UnitInputAndOutput"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonUnitInputAndOutput", + "documentation": "A unit type input serializes no payload. When clients do not\nneed to serialize any data in the payload, they should omit\na payload altogether.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/UnitInputAndOutput", + "body": "", + } + ), + MappingProxyType( + { + "id": "RestJsonUnitInputAllowsAccept", + "documentation": "Servers should allow the accept header to be set to the\ndefault content-type.", + "protocol": "aws.protocols#restJson1", + "method": "POST", + "uri": "/UnitInputAndOutput", + "body": "", + "headers": MappingProxyType({"Accept": "application/json"}), + "appliesTo": "server", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonUnitInputAndOutputNoOutput", + "documentation": "When an operation defines Unit output, the service will respond\nwith an empty payload, and may optionally include the content-type\nheader.", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": "", + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/UnitInputAndOutput", "method": "POST"}), + ), + ], +) + +RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1 = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#RecursiveShapesInputOutputNested1"), + members={ + "foo": {"target": STRING}, + # This needs to reference a schema that isn't defined yet. + # It will be populated with a non-null value at the end of the file. + "nested": None, + }, +) + +RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED2 = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#RecursiveShapesInputOutputNested2"), + members={ + "bar": {"target": STRING}, + "recursiveMember": {"target": RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1}, + }, +) + +RECURSIVE_SHAPES_INPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#RecursiveShapesInput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#RecursiveShapesInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#input")), + ], + members={"nested": {"target": RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1}}, +) + +RECURSIVE_SHAPES_OUTPUT = Schema.collection( + id=ShapeID("aws.protocoltests.restjson#RecursiveShapesOutput"), + traits=[ + Trait.new( + id=ShapeID("smithy.synthetic#originalShapeId"), + value="aws.protocoltests.restjson#RecursiveShapesInputOutput", + ), + Trait.new(id=ShapeID("smithy.api#output")), + ], + members={"nested": {"target": RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1}}, +) + +RECURSIVE_SHAPES = Schema( + id=ShapeID("aws.protocoltests.restjson#RecursiveShapes"), + shape_type=ShapeType.OPERATION, + traits=[ + Trait.new( + id=ShapeID("smithy.test#httpRequestTests"), + value=( + MappingProxyType( + { + "id": "RestJsonRecursiveShapes", + "documentation": "Serializes recursive structures", + "protocol": "aws.protocols#restJson1", + "method": "PUT", + "uri": "/RecursiveShapes", + "body": '{\n "nested": {\n "foo": "Foo1",\n "nested": {\n "bar": "Bar1",\n "recursiveMember": {\n "foo": "Foo2",\n "nested": {\n "bar": "Bar2"\n }\n }\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "nested": MappingProxyType( + { + "foo": "Foo1", + "nested": MappingProxyType( + { + "bar": "Bar1", + "recursiveMember": MappingProxyType( + { + "foo": "Foo2", + "nested": MappingProxyType( + {"bar": "Bar2"} + ), + } + ), + } + ), + } + ) + } + ), + } + ), + ), + ), + Trait.new(id=ShapeID("smithy.api#idempotent")), + Trait.new( + id=ShapeID("smithy.test#httpResponseTests"), + value=( + MappingProxyType( + { + "id": "RestJsonRecursiveShapes", + "documentation": "Serializes recursive structures", + "protocol": "aws.protocols#restJson1", + "code": 200, + "body": '{\n "nested": {\n "foo": "Foo1",\n "nested": {\n "bar": "Bar1",\n "recursiveMember": {\n "foo": "Foo2",\n "nested": {\n "bar": "Bar2"\n }\n }\n }\n }\n}', + "bodyMediaType": "application/json", + "headers": MappingProxyType( + {"Content-Type": "application/json"} + ), + "params": MappingProxyType( + { + "nested": MappingProxyType( + { + "foo": "Foo1", + "nested": MappingProxyType( + { + "bar": "Bar1", + "recursiveMember": MappingProxyType( + { + "foo": "Foo2", + "nested": MappingProxyType( + {"bar": "Bar2"} + ), + } + ), + } + ), + } + ) + } + ), + } + ), + ), + ), + Trait.new( + id=ShapeID("smithy.api#http"), + value=MappingProxyType({"uri": "/RecursiveShapes", "method": "PUT"}), + ), + ], +) + +REST_JSON = Schema( + id=ShapeID("aws.protocoltests.restjson#RestJson"), + shape_type=ShapeType.SERVICE, + traits=[ + Trait.new( + id=ShapeID("aws.auth#sigv4"), value=MappingProxyType({"name": "restjson"}) + ), + Trait.new( + id=ShapeID("smithy.api#title"), value="Sample Rest Json Protocol Service" + ), + Trait.new( + id=ShapeID("aws.api#service"), + value=MappingProxyType({"sdkId": "Rest Json Protocol"}), + ), + Trait.new(id=ShapeID("aws.protocols#restJson1")), + ], +) + +RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1.members["nested"] = Schema.member( + id=RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1.id.with_member("nested"), + target=RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED2, + index=1, +) diff --git a/codegen-output/rest-json-1/src/restjson/auth.py b/codegen-output/rest-json-1/src/restjson/auth.py new file mode 100644 index 000000000..24ca90fec --- /dev/null +++ b/codegen-output/rest-json-1/src/restjson/auth.py @@ -0,0 +1,31 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from typing import Any + +from smithy_core.auth import AuthOption as _smithy_core_auth_AuthOption, AuthParams +from smithy_core.interfaces.auth import ( + AuthOption as _smithy_core_interfaces_auth_AuthOption, +) +from smithy_core.shapes import ShapeID + + +class HTTPAuthSchemeResolver: + def resolve_auth_scheme( + self, auth_parameters: AuthParams[Any, Any] + ) -> list[_smithy_core_interfaces_auth_AuthOption]: + auth_options: list[_smithy_core_interfaces_auth_AuthOption] = [] + + if (option := _generate_sigv4_option(auth_parameters)) is not None: + auth_options.append(option) + + return auth_options + + +def _generate_sigv4_option( + auth_params: AuthParams[Any, Any], +) -> _smithy_core_interfaces_auth_AuthOption | None: + return _smithy_core_auth_AuthOption( + scheme_id=ShapeID("aws.auth#sigv4"), + identity_properties={}, # type: ignore + signer_properties={}, # type: ignore + ) diff --git a/codegen-output/rest-json-1/src/restjson/client.py b/codegen-output/rest-json-1/src/restjson/client.py new file mode 100644 index 000000000..e30fea631 --- /dev/null +++ b/codegen-output/rest-json-1/src/restjson/client.py @@ -0,0 +1,8184 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +import asyncio +from copy import deepcopy +import logging +from typing import Any, Self, cast + +from smithy_aws_core.config import ConfigSource +from smithy_aws_core.identity import AWSCredentialsIdentity +from smithy_aws_core.identity.chain import IdentityChain +from smithy_core.aio.client import ClientCall, RequestPipeline +from smithy_core.aio.eventstream import ( + DuplexEventStream, + InputEventStream, + OutputEventStream, +) +from smithy_core.aio.retries import RetryStrategyResolver +from smithy_core.aio.utils import close +from smithy_core.exceptions import ExpectationNotMetError +from smithy_core.interceptors import InterceptorChain +from smithy_core.types import TypedProperties +from smithy_http.aio.interfaces import HTTPClient +from smithy_http.plugins import user_agent_plugin + +from .config import AsyncRestJsonProtocolConfig, Plugin +from .models import ( + ALL_QUERY_STRING_TYPES, + AllQueryStringTypesInput, + AllQueryStringTypesOutput, + CONSTANT_AND_VARIABLE_QUERY_STRING, + CONSTANT_QUERY_STRING, + CONTENT_TYPE_PARAMETERS, + ConstantAndVariableQueryStringInput, + ConstantAndVariableQueryStringOutput, + ConstantQueryStringInput, + ConstantQueryStringOutput, + ContentTypeParametersInput, + ContentTypeParametersOutput, + DATETIME_OFFSETS, + DOCUMENT_TYPE, + DOCUMENT_TYPE_AS_MAP_VALUE, + DOCUMENT_TYPE_AS_PAYLOAD, + DUPLEX_STREAM, + DUPLEX_STREAM_WITH_DISTINCT_STREAMS, + DUPLEX_STREAM_WITH_INITIAL_MESSAGES, + DatetimeOffsetsInput, + DatetimeOffsetsOutput, + DocumentTypeAsMapValueInput, + DocumentTypeAsMapValueOutput, + DocumentTypeAsPayloadInput, + DocumentTypeAsPayloadOutput, + DocumentTypeInput, + DocumentTypeOutput, + DuplexStreamInput, + DuplexStreamOutput, + DuplexStreamWithDistinctStreamsInput, + DuplexStreamWithDistinctStreamsOutput, + DuplexStreamWithInitialMessagesInput, + DuplexStreamWithInitialMessagesOutput, + EMPTY_INPUT_AND_EMPTY_OUTPUT, + ENDPOINT_OPERATION, + ENDPOINT_WITH_HOST_LABEL_OPERATION, + EmptyInputAndEmptyOutputInput, + EmptyInputAndEmptyOutputOutput, + EndpointOperationInput, + EndpointOperationOutput, + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + EventStream, + FRACTIONAL_SECONDS, + FractionalSecondsInput, + FractionalSecondsOutput, + GREETING_WITH_ERRORS, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HOST_WITH_PATH_OPERATION, + HTTP_CHECKSUM_REQUIRED, + HTTP_EMPTY_PREFIX_HEADERS, + HTTP_ENUM_PAYLOAD, + HTTP_PAYLOAD_TRAITS, + HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE, + HTTP_PAYLOAD_WITH_STRUCTURE, + HTTP_PAYLOAD_WITH_UNION, + HTTP_PREFIX_HEADERS, + HTTP_PREFIX_HEADERS_IN_RESPONSE, + HTTP_QUERY_PARAMS_ONLY_OPERATION, + HTTP_REQUEST_WITH_FLOAT_LABELS, + HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH, + HTTP_REQUEST_WITH_LABELS, + HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT, + HTTP_REQUEST_WITH_REGEX_LITERAL, + HTTP_RESPONSE_CODE, + HTTP_STRING_PAYLOAD, + HostWithPathOperationInput, + HostWithPathOperationOutput, + HttpChecksumRequiredInput, + HttpChecksumRequiredOutput, + HttpEmptyPrefixHeadersInput, + HttpEmptyPrefixHeadersOutput, + HttpEnumPayloadInput, + HttpEnumPayloadOutput, + HttpPayloadTraitsInput, + HttpPayloadTraitsOutput, + HttpPayloadTraitsWithMediaTypeInput, + HttpPayloadTraitsWithMediaTypeOutput, + HttpPayloadWithStructureInput, + HttpPayloadWithStructureOutput, + HttpPayloadWithUnionInput, + HttpPayloadWithUnionOutput, + HttpPrefixHeadersInResponseInput, + HttpPrefixHeadersInResponseOutput, + HttpPrefixHeadersInput, + HttpPrefixHeadersOutput, + HttpQueryParamsOnlyOperationInput, + HttpQueryParamsOnlyOperationOutput, + HttpRequestWithFloatLabelsInput, + HttpRequestWithFloatLabelsOutput, + HttpRequestWithGreedyLabelInPathInput, + HttpRequestWithGreedyLabelInPathOutput, + HttpRequestWithLabelsAndTimestampFormatInput, + HttpRequestWithLabelsAndTimestampFormatOutput, + HttpRequestWithLabelsInput, + HttpRequestWithLabelsOutput, + HttpRequestWithRegexLiteralInput, + HttpRequestWithRegexLiteralOutput, + HttpResponseCodeInput, + HttpResponseCodeOutput, + HttpStringPayloadInput, + HttpStringPayloadOutput, + IGNORE_QUERY_PARAMS_IN_RESPONSE, + INPUT_AND_OUTPUT_WITH_HEADERS, + INPUT_STREAM, + INPUT_STREAM_WITH_INITIAL_REQUEST, + IgnoreQueryParamsInResponseInput, + IgnoreQueryParamsInResponseOutput, + InputAndOutputWithHeadersInput, + InputAndOutputWithHeadersOutput, + InputStreamInput, + InputStreamOutput, + InputStreamWithInitialRequestInput, + InputStreamWithInitialRequestOutput, + JSON_BLOBS, + JSON_ENUMS, + JSON_INT_ENUMS, + JSON_LISTS, + JSON_MAPS, + JSON_TIMESTAMPS, + JSON_UNIONS, + JsonBlobsInput, + JsonBlobsOutput, + JsonEnumsInput, + JsonEnumsOutput, + JsonIntEnumsInput, + JsonIntEnumsOutput, + JsonListsInput, + JsonListsOutput, + JsonMapsInput, + JsonMapsOutput, + JsonTimestampsInput, + JsonTimestampsOutput, + JsonUnionsInput, + JsonUnionsOutput, + MALFORMED_ACCEPT_WITH_BODY, + MALFORMED_ACCEPT_WITH_GENERIC_STRING, + MALFORMED_ACCEPT_WITH_PAYLOAD, + MALFORMED_BLOB, + MALFORMED_BOOLEAN, + MALFORMED_BYTE, + MALFORMED_CONTENT_TYPE_WITHOUT_BODY, + MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT, + MALFORMED_CONTENT_TYPE_WITH_BODY, + MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING, + MALFORMED_CONTENT_TYPE_WITH_PAYLOAD, + MALFORMED_DOUBLE, + MALFORMED_FLOAT, + MALFORMED_INTEGER, + MALFORMED_LIST, + MALFORMED_LONG, + MALFORMED_MAP, + MALFORMED_REQUEST_BODY, + MALFORMED_SHORT, + MALFORMED_STRING, + MALFORMED_TIMESTAMP_BODY_DATE_TIME, + MALFORMED_TIMESTAMP_BODY_DEFAULT, + MALFORMED_TIMESTAMP_BODY_HTTP_DATE, + MALFORMED_TIMESTAMP_HEADER_DATE_TIME, + MALFORMED_TIMESTAMP_HEADER_DEFAULT, + MALFORMED_TIMESTAMP_HEADER_EPOCH, + MALFORMED_TIMESTAMP_PATH_DEFAULT, + MALFORMED_TIMESTAMP_PATH_EPOCH, + MALFORMED_TIMESTAMP_PATH_HTTP_DATE, + MALFORMED_TIMESTAMP_QUERY_DEFAULT, + MALFORMED_TIMESTAMP_QUERY_EPOCH, + MALFORMED_TIMESTAMP_QUERY_HTTP_DATE, + MALFORMED_UNION, + MEDIA_TYPE_HEADER, + MalformedAcceptWithBodyInput, + MalformedAcceptWithBodyOutput, + MalformedAcceptWithGenericStringInput, + MalformedAcceptWithGenericStringOutput, + MalformedAcceptWithPayloadInput, + MalformedAcceptWithPayloadOutput, + MalformedBlobInput, + MalformedBlobOutput, + MalformedBooleanInput, + MalformedBooleanOutput, + MalformedByteInput, + MalformedByteOutput, + MalformedContentTypeWithBodyInput, + MalformedContentTypeWithBodyOutput, + MalformedContentTypeWithGenericStringInput, + MalformedContentTypeWithGenericStringOutput, + MalformedContentTypeWithPayloadInput, + MalformedContentTypeWithPayloadOutput, + MalformedContentTypeWithoutBodyEmptyInputInput, + MalformedContentTypeWithoutBodyEmptyInputOutput, + MalformedContentTypeWithoutBodyInput, + MalformedContentTypeWithoutBodyOutput, + MalformedDoubleInput, + MalformedDoubleOutput, + MalformedFloatInput, + MalformedFloatOutput, + MalformedIntegerInput, + MalformedIntegerOutput, + MalformedListInput, + MalformedListOutput, + MalformedLongInput, + MalformedLongOutput, + MalformedMapInput, + MalformedMapOutput, + MalformedRequestBodyInput, + MalformedRequestBodyOutput, + MalformedShortInput, + MalformedShortOutput, + MalformedStringInput, + MalformedStringOutput, + MalformedTimestampBodyDateTimeInput, + MalformedTimestampBodyDateTimeOutput, + MalformedTimestampBodyDefaultInput, + MalformedTimestampBodyDefaultOutput, + MalformedTimestampBodyHttpDateInput, + MalformedTimestampBodyHttpDateOutput, + MalformedTimestampHeaderDateTimeInput, + MalformedTimestampHeaderDateTimeOutput, + MalformedTimestampHeaderDefaultInput, + MalformedTimestampHeaderDefaultOutput, + MalformedTimestampHeaderEpochInput, + MalformedTimestampHeaderEpochOutput, + MalformedTimestampPathDefaultInput, + MalformedTimestampPathDefaultOutput, + MalformedTimestampPathEpochInput, + MalformedTimestampPathEpochOutput, + MalformedTimestampPathHttpDateInput, + MalformedTimestampPathHttpDateOutput, + MalformedTimestampQueryDefaultInput, + MalformedTimestampQueryDefaultOutput, + MalformedTimestampQueryEpochInput, + MalformedTimestampQueryEpochOutput, + MalformedTimestampQueryHttpDateInput, + MalformedTimestampQueryHttpDateOutput, + MalformedUnionInput, + MalformedUnionOutput, + MediaTypeHeaderInput, + MediaTypeHeaderOutput, + NO_INPUT_AND_NO_OUTPUT, + NO_INPUT_AND_OUTPUT, + NULL_AND_EMPTY_HEADERS_CLIENT, + NULL_AND_EMPTY_HEADERS_SERVER, + NoInputAndNoOutputInput, + NoInputAndNoOutputOutput, + NoInputAndOutputInput, + NoInputAndOutputOutput, + NullAndEmptyHeadersClientInput, + NullAndEmptyHeadersClientOutput, + NullAndEmptyHeadersServerInput, + NullAndEmptyHeadersServerOutput, + OMITS_NULL_SERIALIZES_EMPTY_STRING, + OMITS_SERIALIZING_EMPTY_LISTS, + OPERATION_WITH_DEFAULTS, + OPERATION_WITH_NESTED_STRUCTURE, + OUTPUT_STREAM, + OUTPUT_STREAM_WITH_INITIAL_RESPONSE, + OmitsNullSerializesEmptyStringInput, + OmitsNullSerializesEmptyStringOutput, + OmitsSerializingEmptyListsInput, + OmitsSerializingEmptyListsOutput, + OperationWithDefaultsInput, + OperationWithDefaultsOutput, + OperationWithNestedStructureInput, + OperationWithNestedStructureOutput, + OutputStreamInput, + OutputStreamOutput, + OutputStreamWithInitialResponseInput, + OutputStreamWithInitialResponseOutput, + POST_PLAYER_ACTION, + POST_UNION_WITH_JSON_NAME, + PUT_WITH_CONTENT_ENCODING, + PostPlayerActionInput, + PostPlayerActionOutput, + PostUnionWithJsonNameInput, + PostUnionWithJsonNameOutput, + PutWithContentEncodingInput, + PutWithContentEncodingOutput, + QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL, + QUERY_PARAMS_AS_STRING_LIST_MAP, + QUERY_PRECEDENCE, + QueryIdempotencyTokenAutoFillInput, + QueryIdempotencyTokenAutoFillOutput, + QueryParamsAsStringListMapInput, + QueryParamsAsStringListMapOutput, + QueryPrecedenceInput, + QueryPrecedenceOutput, + RECURSIVE_SHAPES, + RESPONSE_CODE_HTTP_FALLBACK, + RESPONSE_CODE_REQUIRED, + RecursiveShapesInput, + RecursiveShapesOutput, + ResponseCodeHttpFallbackInput, + ResponseCodeHttpFallbackOutput, + ResponseCodeRequiredInput, + ResponseCodeRequiredOutput, + SIMPLE_SCALAR_PROPERTIES, + SPARSE_JSON_LISTS, + SPARSE_JSON_MAPS, + STREAMING_TRAITS, + STREAMING_TRAITS_REQUIRE_LENGTH, + STREAMING_TRAITS_WITH_MEDIA_TYPE, + SimpleScalarPropertiesInput, + SimpleScalarPropertiesOutput, + SparseJsonListsInput, + SparseJsonListsOutput, + SparseJsonMapsInput, + SparseJsonMapsOutput, + StreamingTraitsInput, + StreamingTraitsOutput, + StreamingTraitsRequireLengthInput, + StreamingTraitsRequireLengthOutput, + StreamingTraitsWithMediaTypeInput, + StreamingTraitsWithMediaTypeOutput, + TEST_BODY_STRUCTURE, + TEST_GET_NO_INPUT_NO_PAYLOAD, + TEST_GET_NO_PAYLOAD, + TEST_PAYLOAD_BLOB, + TEST_PAYLOAD_STRUCTURE, + TEST_POST_NO_INPUT_NO_PAYLOAD, + TEST_POST_NO_PAYLOAD, + TIMESTAMP_FORMAT_HEADERS, + TestBodyStructureInput, + TestBodyStructureOutput, + TestGetNoInputNoPayloadInput, + TestGetNoInputNoPayloadOutput, + TestGetNoPayloadInput, + TestGetNoPayloadOutput, + TestPayloadBlobInput, + TestPayloadBlobOutput, + TestPayloadStructureInput, + TestPayloadStructureOutput, + TestPostNoInputNoPayloadInput, + TestPostNoInputNoPayloadOutput, + TestPostNoPayloadInput, + TestPostNoPayloadOutput, + TimestampFormatHeadersInput, + TimestampFormatHeadersOutput, + UNIT_INPUT_AND_OUTPUT, + UnitInputAndOutputInput, + UnitInputAndOutputOutput, + _EventStreamDeserializer, +) +from .user_agent import aws_user_agent_plugin + + +logger = logging.getLogger(__name__) + + +class AsyncRestJsonProtocolClient: + """Client for RestJson""" + + def __init__( + self, + config: AsyncRestJsonProtocolConfig | None = None, + plugins: list[Plugin] | None = None, + ): + """ + Constructor for `AsyncRestJsonProtocolClient`. + + Args: + config: + Optional configuration for the client. Here you can set things like + the endpoint for HTTP services or auth credentials. + plugins: + A list of callables applied once to the client's base configuration. + Their changes are inherited by every operation invocation. + """ + self._config = config + self._plugins = plugins + self._derive_lock = asyncio.Lock() + self._setup_done = False + self._closed = False + self._retry_strategy_resolver = RetryStrategyResolver() + self._client_plugins: list[Plugin] = [aws_user_agent_plugin, user_agent_plugin] + + async def _ensure_setup(self) -> None: + if not self._setup_done: + async with self._derive_lock: + if not self._setup_done: + if self._config is None: + config = await AsyncRestJsonProtocolConfig.resolve() + else: + # Copy so plugins don't mutate the caller's config. + config = deepcopy(self._config) + for plugin in self._client_plugins: + plugin(config) + if self._plugins: + for plugin in self._plugins: + plugin(config) + self._config = config + + if self._config.aws_credentials_identity_resolver is None: + config_context = self._config.resolution_context() + config_file = None + profile_name = None + if config_context is not None: + config_file = await config_context.parsed_profiles() + if config_context.profile_source is ConfigSource.OVERRIDE: + profile_name = config_context.profile_name + self._config.aws_credentials_identity_resolver = ( + await IdentityChain.create( + AWSCredentialsIdentity, + config_file=config_file, + profile_name=profile_name, + region_override=self._config.region, + http_client=cast( + HTTPClient | None, self._config.transport + ), + ) + ) + self._setup_done = True + + async def close(self) -> None: + """Close this client and any resources held by its transport.""" + if self._closed: + return + async with self._derive_lock: + if self._closed: + return + self._closed = True + if self._setup_done and self._config is not None: + await close(self._config.transport) + + async def __aenter__(self) -> Self: + if self._closed: + raise RuntimeError("Cannot enter a client that has been closed.") + return self + + async def __aexit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None: + await self.close() + + async def all_query_string_types( + self, input: AllQueryStringTypesInput, plugins: list[Plugin] | None = None + ) -> AllQueryStringTypesOutput: + """ + This example uses all query string types. + + Args: + input: + An instance of `AllQueryStringTypesInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `AllQueryStringTypesOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=ALL_QUERY_STRING_TYPES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def constant_and_variable_query_string( + self, + input: ConstantAndVariableQueryStringInput, + plugins: list[Plugin] | None = None, + ) -> ConstantAndVariableQueryStringOutput: + """ + This example uses fixed query string params and variable query string + params. The fixed query string parameters and variable parameters must + both be serialized (implementations may need to merge them together). + + Args: + input: + An instance of `ConstantAndVariableQueryStringInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `ConstantAndVariableQueryStringOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=CONSTANT_AND_VARIABLE_QUERY_STRING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def constant_query_string( + self, input: ConstantQueryStringInput, plugins: list[Plugin] | None = None + ) -> ConstantQueryStringOutput: + """ + This example uses a constant query string parameters and a label. This + simply tests that labels and query string parameters are compatible. The + fixed query string parameter named \"hello\" should in no way conflict + with the label, `{hello}`. + + Args: + input: + An instance of `ConstantQueryStringInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `ConstantQueryStringOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=CONSTANT_QUERY_STRING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def content_type_parameters( + self, input: ContentTypeParametersInput, plugins: list[Plugin] | None = None + ) -> ContentTypeParametersOutput: + """ + The example tests how servers must support requests containing a + `Content-Type` header with parameters. + + Args: + input: + An instance of `ContentTypeParametersInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `ContentTypeParametersOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=CONTENT_TYPE_PARAMETERS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def datetime_offsets( + self, input: DatetimeOffsetsInput, plugins: list[Plugin] | None = None + ) -> DatetimeOffsetsOutput: + """ + Invokes the DatetimeOffsets operation. + + Args: + input: + An instance of `DatetimeOffsetsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `DatetimeOffsetsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=DATETIME_OFFSETS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def document_type( + self, input: DocumentTypeInput, plugins: list[Plugin] | None = None + ) -> DocumentTypeOutput: + """ + This example serializes a document as part of the payload. + + Args: + input: + An instance of `DocumentTypeInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `DocumentTypeOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=DOCUMENT_TYPE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def document_type_as_map_value( + self, input: DocumentTypeAsMapValueInput, plugins: list[Plugin] | None = None + ) -> DocumentTypeAsMapValueOutput: + """ + This example serializes documents as the value of maps. + + Args: + input: + An instance of `DocumentTypeAsMapValueInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `DocumentTypeAsMapValueOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=DOCUMENT_TYPE_AS_MAP_VALUE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def document_type_as_payload( + self, input: DocumentTypeAsPayloadInput, plugins: list[Plugin] | None = None + ) -> DocumentTypeAsPayloadOutput: + """ + This example serializes a document as the entire HTTP payload. + + Args: + input: + An instance of `DocumentTypeAsPayloadInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `DocumentTypeAsPayloadOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=DOCUMENT_TYPE_AS_PAYLOAD, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def duplex_stream( + self, input: DuplexStreamInput, plugins: list[Plugin] | None = None + ) -> DuplexEventStream[EventStream, EventStream, DuplexStreamOutput]: + """ + Invokes the DuplexStream operation. + + Args: + input: + An instance of `DuplexStreamInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + A `DuplexEventStream` for bidirectional streaming. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=DUPLEX_STREAM, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline.duplex_stream( + call, EventStream, EventStream, _EventStreamDeserializer().deserialize + ) + + async def duplex_stream_with_distinct_streams( + self, + input: DuplexStreamWithDistinctStreamsInput, + plugins: list[Plugin] | None = None, + ) -> InputEventStream[EventStream, DuplexStreamWithDistinctStreamsOutput]: + """ + Invokes the DuplexStreamWithDistinctStreams operation. + + Args: + input: + An instance of `DuplexStreamWithDistinctStreamsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An `InputEventStream` for client-to-server streaming. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=DUPLEX_STREAM_WITH_DISTINCT_STREAMS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline.input_stream(call, EventStream) + + async def duplex_stream_with_initial_messages( + self, + input: DuplexStreamWithInitialMessagesInput, + plugins: list[Plugin] | None = None, + ) -> DuplexEventStream[ + EventStream, EventStream, DuplexStreamWithInitialMessagesOutput + ]: + """ + Invokes the DuplexStreamWithInitialMessages operation. + + Args: + input: + An instance of `DuplexStreamWithInitialMessagesInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + A `DuplexEventStream` for bidirectional streaming. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=DUPLEX_STREAM_WITH_INITIAL_MESSAGES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline.duplex_stream( + call, EventStream, EventStream, _EventStreamDeserializer().deserialize + ) + + async def empty_input_and_empty_output( + self, input: EmptyInputAndEmptyOutputInput, plugins: list[Plugin] | None = None + ) -> EmptyInputAndEmptyOutputOutput: + """ + The example tests how requests and responses are serialized when + there's no request or response payload because the operation has an + empty input and empty output structure that reuses the same shape. While + this should be rare, code generators must support this. + + Args: + input: + An instance of `EmptyInputAndEmptyOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EmptyInputAndEmptyOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=EMPTY_INPUT_AND_EMPTY_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def endpoint_operation( + self, input: EndpointOperationInput, plugins: list[Plugin] | None = None + ) -> EndpointOperationOutput: + """ + Invokes the EndpointOperation operation. + + Args: + input: + An instance of `EndpointOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EndpointOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=ENDPOINT_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def endpoint_with_host_label_operation( + self, + input: EndpointWithHostLabelOperationInput, + plugins: list[Plugin] | None = None, + ) -> EndpointWithHostLabelOperationOutput: + """ + Invokes the EndpointWithHostLabelOperation operation. + + Args: + input: + An instance of `EndpointWithHostLabelOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `EndpointWithHostLabelOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=ENDPOINT_WITH_HOST_LABEL_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def fractional_seconds( + self, input: FractionalSecondsInput, plugins: list[Plugin] | None = None + ) -> FractionalSecondsOutput: + """ + Invokes the FractionalSeconds operation. + + Args: + input: + An instance of `FractionalSecondsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `FractionalSecondsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=FRACTIONAL_SECONDS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def greeting_with_errors( + self, input: GreetingWithErrorsInput, plugins: list[Plugin] | None = None + ) -> GreetingWithErrorsOutput: + """ + This operation has four possible return values: 1. A successful response + in the form of GreetingWithErrorsOutput 2. An InvalidGreeting error. 3. + A BadRequest error. 4. A FooError. Implementations must be able to + successfully take a response and properly (de)serialize successful and + error responses based on the the presence of the + + Args: + input: + An instance of `GreetingWithErrorsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `GreetingWithErrorsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=GREETING_WITH_ERRORS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def host_with_path_operation( + self, input: HostWithPathOperationInput, plugins: list[Plugin] | None = None + ) -> HostWithPathOperationOutput: + """ + Invokes the HostWithPathOperation operation. + + Args: + input: + An instance of `HostWithPathOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HostWithPathOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HOST_WITH_PATH_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_checksum_required( + self, input: HttpChecksumRequiredInput, plugins: list[Plugin] | None = None + ) -> HttpChecksumRequiredOutput: + """ + This example tests httpChecksumRequired trait + + Args: + input: + An instance of `HttpChecksumRequiredInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpChecksumRequiredOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_CHECKSUM_REQUIRED, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_empty_prefix_headers( + self, input: HttpEmptyPrefixHeadersInput, plugins: list[Plugin] | None = None + ) -> HttpEmptyPrefixHeadersOutput: + """ + Clients that perform this test extract all headers from the response. + + Args: + input: + An instance of `HttpEmptyPrefixHeadersInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpEmptyPrefixHeadersOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_EMPTY_PREFIX_HEADERS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_enum_payload( + self, input: HttpEnumPayloadInput, plugins: list[Plugin] | None = None + ) -> HttpEnumPayloadOutput: + """ + Invokes the HttpEnumPayload operation. + + Args: + input: + An instance of `HttpEnumPayloadInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpEnumPayloadOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_ENUM_PAYLOAD, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_payload_traits( + self, input: HttpPayloadTraitsInput, plugins: list[Plugin] | None = None + ) -> HttpPayloadTraitsOutput: + """ + This example serializes a blob shape in the payload. In this example, no + JSON document is synthesized because the payload is not a structure or a + union type. + + Args: + input: + An instance of `HttpPayloadTraitsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpPayloadTraitsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_PAYLOAD_TRAITS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_payload_traits_with_media_type( + self, + input: HttpPayloadTraitsWithMediaTypeInput, + plugins: list[Plugin] | None = None, + ) -> HttpPayloadTraitsWithMediaTypeOutput: + """ + This example uses a `@mediaType` trait on the payload to force a + custom content-type to be serialized. + + Args: + input: + An instance of `HttpPayloadTraitsWithMediaTypeInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpPayloadTraitsWithMediaTypeOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_payload_with_structure( + self, input: HttpPayloadWithStructureInput, plugins: list[Plugin] | None = None + ) -> HttpPayloadWithStructureOutput: + """ + This example serializes a structure in the payload. Note that + serializing a structure changes the wrapper element name to match the + targeted structure. + + Args: + input: + An instance of `HttpPayloadWithStructureInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpPayloadWithStructureOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_PAYLOAD_WITH_STRUCTURE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_payload_with_union( + self, input: HttpPayloadWithUnionInput, plugins: list[Plugin] | None = None + ) -> HttpPayloadWithUnionOutput: + """ + This example serializes a union in the payload. + + Args: + input: + An instance of `HttpPayloadWithUnionInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpPayloadWithUnionOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_PAYLOAD_WITH_UNION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_prefix_headers( + self, input: HttpPrefixHeadersInput, plugins: list[Plugin] | None = None + ) -> HttpPrefixHeadersOutput: + """ + This examples adds headers to the input of a request and response by + prefix. + + Args: + input: + An instance of `HttpPrefixHeadersInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpPrefixHeadersOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_PREFIX_HEADERS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_prefix_headers_in_response( + self, + input: HttpPrefixHeadersInResponseInput, + plugins: list[Plugin] | None = None, + ) -> HttpPrefixHeadersInResponseOutput: + """ + Clients that perform this test extract all headers from the response. + + Args: + input: + An instance of `HttpPrefixHeadersInResponseInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpPrefixHeadersInResponseOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_PREFIX_HEADERS_IN_RESPONSE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_query_params_only_operation( + self, + input: HttpQueryParamsOnlyOperationInput, + plugins: list[Plugin] | None = None, + ) -> HttpQueryParamsOnlyOperationOutput: + """ + This example tests httpQueryParams when no other query parameters exist. + + Args: + input: + An instance of `HttpQueryParamsOnlyOperationInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpQueryParamsOnlyOperationOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_QUERY_PARAMS_ONLY_OPERATION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_request_with_float_labels( + self, + input: HttpRequestWithFloatLabelsInput, + plugins: list[Plugin] | None = None, + ) -> HttpRequestWithFloatLabelsOutput: + """ + Invokes the HttpRequestWithFloatLabels operation. + + Args: + input: + An instance of `HttpRequestWithFloatLabelsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpRequestWithFloatLabelsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_REQUEST_WITH_FLOAT_LABELS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_request_with_greedy_label_in_path( + self, + input: HttpRequestWithGreedyLabelInPathInput, + plugins: list[Plugin] | None = None, + ) -> HttpRequestWithGreedyLabelInPathOutput: + """ + Invokes the HttpRequestWithGreedyLabelInPath operation. + + Args: + input: + An instance of `HttpRequestWithGreedyLabelInPathInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpRequestWithGreedyLabelInPathOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_request_with_labels( + self, input: HttpRequestWithLabelsInput, plugins: list[Plugin] | None = None + ) -> HttpRequestWithLabelsOutput: + """ + The example tests how requests are serialized when there's no input + payload but there are HTTP labels. + + Args: + input: + An instance of `HttpRequestWithLabelsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpRequestWithLabelsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_REQUEST_WITH_LABELS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_request_with_labels_and_timestamp_format( + self, + input: HttpRequestWithLabelsAndTimestampFormatInput, + plugins: list[Plugin] | None = None, + ) -> HttpRequestWithLabelsAndTimestampFormatOutput: + """ + The example tests how requests serialize different timestamp formats in + the URI path. + + Args: + input: + An instance of `HttpRequestWithLabelsAndTimestampFormatInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpRequestWithLabelsAndTimestampFormatOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_request_with_regex_literal( + self, + input: HttpRequestWithRegexLiteralInput, + plugins: list[Plugin] | None = None, + ) -> HttpRequestWithRegexLiteralOutput: + """ + Invokes the HttpRequestWithRegexLiteral operation. + + Args: + input: + An instance of `HttpRequestWithRegexLiteralInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpRequestWithRegexLiteralOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_REQUEST_WITH_REGEX_LITERAL, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_response_code( + self, input: HttpResponseCodeInput, plugins: list[Plugin] | None = None + ) -> HttpResponseCodeOutput: + """ + Invokes the HttpResponseCode operation. + + Args: + input: + An instance of `HttpResponseCodeInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpResponseCodeOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_RESPONSE_CODE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def http_string_payload( + self, input: HttpStringPayloadInput, plugins: list[Plugin] | None = None + ) -> HttpStringPayloadOutput: + """ + Invokes the HttpStringPayload operation. + + Args: + input: + An instance of `HttpStringPayloadInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `HttpStringPayloadOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=HTTP_STRING_PAYLOAD, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def ignore_query_params_in_response( + self, + input: IgnoreQueryParamsInResponseInput, + plugins: list[Plugin] | None = None, + ) -> IgnoreQueryParamsInResponseOutput: + """ + This example ensures that query string bound request parameters are + serialized in the body of responses if the structure is used in both the + request and response. + + Args: + input: + An instance of `IgnoreQueryParamsInResponseInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `IgnoreQueryParamsInResponseOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=IGNORE_QUERY_PARAMS_IN_RESPONSE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def input_and_output_with_headers( + self, input: InputAndOutputWithHeadersInput, plugins: list[Plugin] | None = None + ) -> InputAndOutputWithHeadersOutput: + """ + The example tests how requests and responses are serialized when there + is no input or output payload but there are HTTP header bindings. + + Args: + input: + An instance of `InputAndOutputWithHeadersInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `InputAndOutputWithHeadersOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=INPUT_AND_OUTPUT_WITH_HEADERS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def input_stream( + self, input: InputStreamInput, plugins: list[Plugin] | None = None + ) -> InputEventStream[EventStream, InputStreamOutput]: + """ + Invokes the InputStream operation. + + Args: + input: + An instance of `InputStreamInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An `InputEventStream` for client-to-server streaming. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=INPUT_STREAM, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline.input_stream(call, EventStream) + + async def input_stream_with_initial_request( + self, + input: InputStreamWithInitialRequestInput, + plugins: list[Plugin] | None = None, + ) -> InputEventStream[EventStream, InputStreamWithInitialRequestOutput]: + """ + Invokes the InputStreamWithInitialRequest operation. + + Args: + input: + An instance of `InputStreamWithInitialRequestInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An `InputEventStream` for client-to-server streaming. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=INPUT_STREAM_WITH_INITIAL_REQUEST, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline.input_stream(call, EventStream) + + async def json_blobs( + self, input: JsonBlobsInput, plugins: list[Plugin] | None = None + ) -> JsonBlobsOutput: + """ + Blobs are base64 encoded + + Args: + input: + An instance of `JsonBlobsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonBlobsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_BLOBS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_enums( + self, input: JsonEnumsInput, plugins: list[Plugin] | None = None + ) -> JsonEnumsOutput: + """ + This example serializes enums as top level properties, in lists, sets, + and maps. + + Args: + input: + An instance of `JsonEnumsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonEnumsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_ENUMS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_int_enums( + self, input: JsonIntEnumsInput, plugins: list[Plugin] | None = None + ) -> JsonIntEnumsOutput: + """ + This example serializes intEnums as top level properties, in lists, + sets, and maps. + + Args: + input: + An instance of `JsonIntEnumsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonIntEnumsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_INT_ENUMS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_lists( + self, input: JsonListsInput, plugins: list[Plugin] | None = None + ) -> JsonListsOutput: + """ + This test case serializes JSON lists for the following cases for both + input and output: 1. Normal JSON lists. 2. Normal JSON sets. 3. JSON + lists of lists. 4. Lists of structures. + + Args: + input: + An instance of `JsonListsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonListsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_LISTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_maps( + self, input: JsonMapsInput, plugins: list[Plugin] | None = None + ) -> JsonMapsOutput: + """ + The example tests basic map serialization. + + Args: + input: + An instance of `JsonMapsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonMapsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_MAPS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_timestamps( + self, input: JsonTimestampsInput, plugins: list[Plugin] | None = None + ) -> JsonTimestampsOutput: + """ + This tests how timestamps are serialized, including using the default + format of date-time and various @timestampFormat trait values. + + Args: + input: + An instance of `JsonTimestampsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonTimestampsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_TIMESTAMPS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def json_unions( + self, input: JsonUnionsInput, plugins: list[Plugin] | None = None + ) -> JsonUnionsOutput: + """ + This operation uses unions for inputs and outputs. + + Args: + input: + An instance of `JsonUnionsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `JsonUnionsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=JSON_UNIONS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_accept_with_body( + self, input: MalformedAcceptWithBodyInput, plugins: list[Plugin] | None = None + ) -> MalformedAcceptWithBodyOutput: + """ + Invokes the MalformedAcceptWithBody operation. + + Args: + input: + An instance of `MalformedAcceptWithBodyInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedAcceptWithBodyOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_ACCEPT_WITH_BODY, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_accept_with_generic_string( + self, + input: MalformedAcceptWithGenericStringInput, + plugins: list[Plugin] | None = None, + ) -> MalformedAcceptWithGenericStringOutput: + """ + Invokes the MalformedAcceptWithGenericString operation. + + Args: + input: + An instance of `MalformedAcceptWithGenericStringInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedAcceptWithGenericStringOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_ACCEPT_WITH_GENERIC_STRING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_accept_with_payload( + self, + input: MalformedAcceptWithPayloadInput, + plugins: list[Plugin] | None = None, + ) -> MalformedAcceptWithPayloadOutput: + """ + Invokes the MalformedAcceptWithPayload operation. + + Args: + input: + An instance of `MalformedAcceptWithPayloadInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedAcceptWithPayloadOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_ACCEPT_WITH_PAYLOAD, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_blob( + self, input: MalformedBlobInput, plugins: list[Plugin] | None = None + ) -> MalformedBlobOutput: + """ + Invokes the MalformedBlob operation. + + Args: + input: + An instance of `MalformedBlobInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedBlobOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_BLOB, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_boolean( + self, input: MalformedBooleanInput, plugins: list[Plugin] | None = None + ) -> MalformedBooleanOutput: + """ + Invokes the MalformedBoolean operation. + + Args: + input: + An instance of `MalformedBooleanInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedBooleanOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_BOOLEAN, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_byte( + self, input: MalformedByteInput, plugins: list[Plugin] | None = None + ) -> MalformedByteOutput: + """ + Invokes the MalformedByte operation. + + Args: + input: + An instance of `MalformedByteInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedByteOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_BYTE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_content_type_with_body( + self, + input: MalformedContentTypeWithBodyInput, + plugins: list[Plugin] | None = None, + ) -> MalformedContentTypeWithBodyOutput: + """ + Invokes the MalformedContentTypeWithBody operation. + + Args: + input: + An instance of `MalformedContentTypeWithBodyInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedContentTypeWithBodyOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_CONTENT_TYPE_WITH_BODY, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_content_type_with_generic_string( + self, + input: MalformedContentTypeWithGenericStringInput, + plugins: list[Plugin] | None = None, + ) -> MalformedContentTypeWithGenericStringOutput: + """ + Invokes the MalformedContentTypeWithGenericString operation. + + Args: + input: + An instance of `MalformedContentTypeWithGenericStringInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedContentTypeWithGenericStringOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_content_type_without_body( + self, + input: MalformedContentTypeWithoutBodyInput, + plugins: list[Plugin] | None = None, + ) -> MalformedContentTypeWithoutBodyOutput: + """ + Invokes the MalformedContentTypeWithoutBody operation. + + Args: + input: + An instance of `MalformedContentTypeWithoutBodyInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedContentTypeWithoutBodyOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_CONTENT_TYPE_WITHOUT_BODY, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_content_type_without_body_empty_input( + self, + input: MalformedContentTypeWithoutBodyEmptyInputInput, + plugins: list[Plugin] | None = None, + ) -> MalformedContentTypeWithoutBodyEmptyInputOutput: + """ + Invokes the MalformedContentTypeWithoutBodyEmptyInput operation. + + Args: + input: + An instance of `MalformedContentTypeWithoutBodyEmptyInputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedContentTypeWithoutBodyEmptyInputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_content_type_with_payload( + self, + input: MalformedContentTypeWithPayloadInput, + plugins: list[Plugin] | None = None, + ) -> MalformedContentTypeWithPayloadOutput: + """ + Invokes the MalformedContentTypeWithPayload operation. + + Args: + input: + An instance of `MalformedContentTypeWithPayloadInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedContentTypeWithPayloadOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_CONTENT_TYPE_WITH_PAYLOAD, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_double( + self, input: MalformedDoubleInput, plugins: list[Plugin] | None = None + ) -> MalformedDoubleOutput: + """ + Invokes the MalformedDouble operation. + + Args: + input: + An instance of `MalformedDoubleInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedDoubleOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_DOUBLE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_float( + self, input: MalformedFloatInput, plugins: list[Plugin] | None = None + ) -> MalformedFloatOutput: + """ + Invokes the MalformedFloat operation. + + Args: + input: + An instance of `MalformedFloatInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedFloatOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_FLOAT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_integer( + self, input: MalformedIntegerInput, plugins: list[Plugin] | None = None + ) -> MalformedIntegerOutput: + """ + Invokes the MalformedInteger operation. + + Args: + input: + An instance of `MalformedIntegerInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedIntegerOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_INTEGER, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_list( + self, input: MalformedListInput, plugins: list[Plugin] | None = None + ) -> MalformedListOutput: + """ + Invokes the MalformedList operation. + + Args: + input: + An instance of `MalformedListInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedListOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_LIST, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_long( + self, input: MalformedLongInput, plugins: list[Plugin] | None = None + ) -> MalformedLongOutput: + """ + Invokes the MalformedLong operation. + + Args: + input: + An instance of `MalformedLongInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedLongOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_LONG, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_map( + self, input: MalformedMapInput, plugins: list[Plugin] | None = None + ) -> MalformedMapOutput: + """ + Invokes the MalformedMap operation. + + Args: + input: + An instance of `MalformedMapInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedMapOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_MAP, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_request_body( + self, input: MalformedRequestBodyInput, plugins: list[Plugin] | None = None + ) -> MalformedRequestBodyOutput: + """ + Invokes the MalformedRequestBody operation. + + Args: + input: + An instance of `MalformedRequestBodyInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedRequestBodyOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_REQUEST_BODY, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_short( + self, input: MalformedShortInput, plugins: list[Plugin] | None = None + ) -> MalformedShortOutput: + """ + Invokes the MalformedShort operation. + + Args: + input: + An instance of `MalformedShortInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedShortOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_SHORT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_string( + self, input: MalformedStringInput, plugins: list[Plugin] | None = None + ) -> MalformedStringOutput: + """ + Invokes the MalformedString operation. + + Args: + input: + An instance of `MalformedStringInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedStringOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_STRING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_body_date_time( + self, + input: MalformedTimestampBodyDateTimeInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampBodyDateTimeOutput: + """ + Invokes the MalformedTimestampBodyDateTime operation. + + Args: + input: + An instance of `MalformedTimestampBodyDateTimeInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampBodyDateTimeOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_BODY_DATE_TIME, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_body_default( + self, + input: MalformedTimestampBodyDefaultInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampBodyDefaultOutput: + """ + Invokes the MalformedTimestampBodyDefault operation. + + Args: + input: + An instance of `MalformedTimestampBodyDefaultInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampBodyDefaultOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_BODY_DEFAULT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_body_http_date( + self, + input: MalformedTimestampBodyHttpDateInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampBodyHttpDateOutput: + """ + Invokes the MalformedTimestampBodyHttpDate operation. + + Args: + input: + An instance of `MalformedTimestampBodyHttpDateInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampBodyHttpDateOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_BODY_HTTP_DATE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_header_date_time( + self, + input: MalformedTimestampHeaderDateTimeInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampHeaderDateTimeOutput: + """ + Invokes the MalformedTimestampHeaderDateTime operation. + + Args: + input: + An instance of `MalformedTimestampHeaderDateTimeInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampHeaderDateTimeOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_HEADER_DATE_TIME, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_header_default( + self, + input: MalformedTimestampHeaderDefaultInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampHeaderDefaultOutput: + """ + Invokes the MalformedTimestampHeaderDefault operation. + + Args: + input: + An instance of `MalformedTimestampHeaderDefaultInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampHeaderDefaultOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_HEADER_DEFAULT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_header_epoch( + self, + input: MalformedTimestampHeaderEpochInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampHeaderEpochOutput: + """ + Invokes the MalformedTimestampHeaderEpoch operation. + + Args: + input: + An instance of `MalformedTimestampHeaderEpochInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampHeaderEpochOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_HEADER_EPOCH, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_path_default( + self, + input: MalformedTimestampPathDefaultInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampPathDefaultOutput: + """ + Invokes the MalformedTimestampPathDefault operation. + + Args: + input: + An instance of `MalformedTimestampPathDefaultInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampPathDefaultOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_PATH_DEFAULT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_path_epoch( + self, + input: MalformedTimestampPathEpochInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampPathEpochOutput: + """ + Invokes the MalformedTimestampPathEpoch operation. + + Args: + input: + An instance of `MalformedTimestampPathEpochInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampPathEpochOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_PATH_EPOCH, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_path_http_date( + self, + input: MalformedTimestampPathHttpDateInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampPathHttpDateOutput: + """ + Invokes the MalformedTimestampPathHttpDate operation. + + Args: + input: + An instance of `MalformedTimestampPathHttpDateInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampPathHttpDateOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_PATH_HTTP_DATE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_query_default( + self, + input: MalformedTimestampQueryDefaultInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampQueryDefaultOutput: + """ + Invokes the MalformedTimestampQueryDefault operation. + + Args: + input: + An instance of `MalformedTimestampQueryDefaultInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampQueryDefaultOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_QUERY_DEFAULT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_query_epoch( + self, + input: MalformedTimestampQueryEpochInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampQueryEpochOutput: + """ + Invokes the MalformedTimestampQueryEpoch operation. + + Args: + input: + An instance of `MalformedTimestampQueryEpochInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampQueryEpochOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_QUERY_EPOCH, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_timestamp_query_http_date( + self, + input: MalformedTimestampQueryHttpDateInput, + plugins: list[Plugin] | None = None, + ) -> MalformedTimestampQueryHttpDateOutput: + """ + Invokes the MalformedTimestampQueryHttpDate operation. + + Args: + input: + An instance of `MalformedTimestampQueryHttpDateInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedTimestampQueryHttpDateOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_TIMESTAMP_QUERY_HTTP_DATE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def malformed_union( + self, input: MalformedUnionInput, plugins: list[Plugin] | None = None + ) -> MalformedUnionOutput: + """ + Invokes the MalformedUnion operation. + + Args: + input: + An instance of `MalformedUnionInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MalformedUnionOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MALFORMED_UNION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def media_type_header( + self, input: MediaTypeHeaderInput, plugins: list[Plugin] | None = None + ) -> MediaTypeHeaderOutput: + """ + This example ensures that mediaType strings are base64 encoded in + headers. + + Args: + input: + An instance of `MediaTypeHeaderInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `MediaTypeHeaderOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=MEDIA_TYPE_HEADER, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def no_input_and_no_output( + self, input: NoInputAndNoOutputInput, plugins: list[Plugin] | None = None + ) -> NoInputAndNoOutputOutput: + """ + The example tests how requests and responses are serialized when + there's no request or response payload because the operation has no + input or output. While this should be rare, code generators must support + this. + + Args: + input: + An instance of `NoInputAndNoOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NoInputAndNoOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NO_INPUT_AND_NO_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def no_input_and_output( + self, input: NoInputAndOutputInput, plugins: list[Plugin] | None = None + ) -> NoInputAndOutputOutput: + """ + The example tests how requests and responses are serialized when + there's no request or response payload because the operation has no + input and the output is empty. While this should be rare, code + generators must support this. + + Args: + input: + An instance of `NoInputAndOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NoInputAndOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NO_INPUT_AND_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def null_and_empty_headers_client( + self, input: NullAndEmptyHeadersClientInput, plugins: list[Plugin] | None = None + ) -> NullAndEmptyHeadersClientOutput: + """ + Null headers are not sent over the wire, empty headers are serialized to + \"\" + + Args: + input: + An instance of `NullAndEmptyHeadersClientInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NullAndEmptyHeadersClientOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NULL_AND_EMPTY_HEADERS_CLIENT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def null_and_empty_headers_server( + self, input: NullAndEmptyHeadersServerInput, plugins: list[Plugin] | None = None + ) -> NullAndEmptyHeadersServerOutput: + """ + Null headers are not sent over the wire, empty headers are serialized to + \"\" + + Args: + input: + An instance of `NullAndEmptyHeadersServerInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `NullAndEmptyHeadersServerOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=NULL_AND_EMPTY_HEADERS_SERVER, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def omits_null_serializes_empty_string( + self, + input: OmitsNullSerializesEmptyStringInput, + plugins: list[Plugin] | None = None, + ) -> OmitsNullSerializesEmptyStringOutput: + """ + Omits null, but serializes empty string value. + + Args: + input: + An instance of `OmitsNullSerializesEmptyStringInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `OmitsNullSerializesEmptyStringOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OMITS_NULL_SERIALIZES_EMPTY_STRING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def omits_serializing_empty_lists( + self, + input: OmitsSerializingEmptyListsInput, + plugins: list[Plugin] | None = None, + ) -> OmitsSerializingEmptyListsOutput: + """ + Omits serializing empty lists. Because empty strings are serilized as + `Foo=`, empty lists cannot also be serialized as `Foo=` and instead + must be omitted. + + Args: + input: + An instance of `OmitsSerializingEmptyListsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `OmitsSerializingEmptyListsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OMITS_SERIALIZING_EMPTY_LISTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def operation_with_defaults( + self, input: OperationWithDefaultsInput, plugins: list[Plugin] | None = None + ) -> OperationWithDefaultsOutput: + """ + Invokes the OperationWithDefaults operation. + + Args: + input: + An instance of `OperationWithDefaultsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `OperationWithDefaultsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OPERATION_WITH_DEFAULTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def operation_with_nested_structure( + self, + input: OperationWithNestedStructureInput, + plugins: list[Plugin] | None = None, + ) -> OperationWithNestedStructureOutput: + """ + Invokes the OperationWithNestedStructure operation. + + Args: + input: + An instance of `OperationWithNestedStructureInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `OperationWithNestedStructureOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OPERATION_WITH_NESTED_STRUCTURE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def output_stream( + self, input: OutputStreamInput, plugins: list[Plugin] | None = None + ) -> OutputEventStream[EventStream, OutputStreamOutput]: + """ + Invokes the OutputStream operation. + + Args: + input: + An instance of `OutputStreamInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An `OutputEventStream` for server-to-client streaming. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OUTPUT_STREAM, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline.output_stream( + call, EventStream, _EventStreamDeserializer().deserialize + ) + + async def output_stream_with_initial_response( + self, + input: OutputStreamWithInitialResponseInput, + plugins: list[Plugin] | None = None, + ) -> OutputEventStream[EventStream, OutputStreamWithInitialResponseOutput]: + """ + Invokes the OutputStreamWithInitialResponse operation. + + Args: + input: + An instance of `OutputStreamWithInitialResponseInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An `OutputEventStream` for server-to-client streaming. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=OUTPUT_STREAM_WITH_INITIAL_RESPONSE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline.output_stream( + call, EventStream, _EventStreamDeserializer().deserialize + ) + + async def post_player_action( + self, input: PostPlayerActionInput, plugins: list[Plugin] | None = None + ) -> PostPlayerActionOutput: + """ + This operation defines a union with a Unit member. + + Args: + input: + An instance of `PostPlayerActionInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `PostPlayerActionOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=POST_PLAYER_ACTION, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def post_union_with_json_name( + self, input: PostUnionWithJsonNameInput, plugins: list[Plugin] | None = None + ) -> PostUnionWithJsonNameOutput: + """ + This operation defines a union that uses jsonName on some members. + + Args: + input: + An instance of `PostUnionWithJsonNameInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `PostUnionWithJsonNameOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=POST_UNION_WITH_JSON_NAME, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def put_with_content_encoding( + self, input: PutWithContentEncodingInput, plugins: list[Plugin] | None = None + ) -> PutWithContentEncodingOutput: + """ + Invokes the PutWithContentEncoding operation. + + Args: + input: + An instance of `PutWithContentEncodingInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `PutWithContentEncodingOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=PUT_WITH_CONTENT_ENCODING, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def query_idempotency_token_auto_fill( + self, + input: QueryIdempotencyTokenAutoFillInput, + plugins: list[Plugin] | None = None, + ) -> QueryIdempotencyTokenAutoFillOutput: + """ + Automatically adds idempotency tokens. + + Args: + input: + An instance of `QueryIdempotencyTokenAutoFillInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `QueryIdempotencyTokenAutoFillOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def query_params_as_string_list_map( + self, + input: QueryParamsAsStringListMapInput, + plugins: list[Plugin] | None = None, + ) -> QueryParamsAsStringListMapOutput: + """ + Invokes the QueryParamsAsStringListMap operation. + + Args: + input: + An instance of `QueryParamsAsStringListMapInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `QueryParamsAsStringListMapOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=QUERY_PARAMS_AS_STRING_LIST_MAP, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def query_precedence( + self, input: QueryPrecedenceInput, plugins: list[Plugin] | None = None + ) -> QueryPrecedenceOutput: + """ + Invokes the QueryPrecedence operation. + + Args: + input: + An instance of `QueryPrecedenceInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `QueryPrecedenceOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=QUERY_PRECEDENCE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def recursive_shapes( + self, input: RecursiveShapesInput, plugins: list[Plugin] | None = None + ) -> RecursiveShapesOutput: + """ + Recursive shapes + + Args: + input: + An instance of `RecursiveShapesInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `RecursiveShapesOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=RECURSIVE_SHAPES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def response_code_http_fallback( + self, input: ResponseCodeHttpFallbackInput, plugins: list[Plugin] | None = None + ) -> ResponseCodeHttpFallbackOutput: + """ + Invokes the ResponseCodeHttpFallback operation. + + Args: + input: + An instance of `ResponseCodeHttpFallbackInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `ResponseCodeHttpFallbackOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=RESPONSE_CODE_HTTP_FALLBACK, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def response_code_required( + self, input: ResponseCodeRequiredInput, plugins: list[Plugin] | None = None + ) -> ResponseCodeRequiredOutput: + """ + Invokes the ResponseCodeRequired operation. + + Args: + input: + An instance of `ResponseCodeRequiredInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `ResponseCodeRequiredOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=RESPONSE_CODE_REQUIRED, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def simple_scalar_properties( + self, input: SimpleScalarPropertiesInput, plugins: list[Plugin] | None = None + ) -> SimpleScalarPropertiesOutput: + """ + Invokes the SimpleScalarProperties operation. + + Args: + input: + An instance of `SimpleScalarPropertiesInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `SimpleScalarPropertiesOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=SIMPLE_SCALAR_PROPERTIES, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def sparse_json_lists( + self, input: SparseJsonListsInput, plugins: list[Plugin] | None = None + ) -> SparseJsonListsOutput: + """ + Invokes the SparseJsonLists operation. + + Args: + input: + An instance of `SparseJsonListsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `SparseJsonListsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=SPARSE_JSON_LISTS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def sparse_json_maps( + self, input: SparseJsonMapsInput, plugins: list[Plugin] | None = None + ) -> SparseJsonMapsOutput: + """ + This example tests sparse map serialization. + + Args: + input: + An instance of `SparseJsonMapsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `SparseJsonMapsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=SPARSE_JSON_MAPS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def streaming_traits( + self, input: StreamingTraitsInput, plugins: list[Plugin] | None = None + ) -> StreamingTraitsOutput: + """ + This examples serializes a streaming blob shape in the request body. In + this example, no JSON document is synthesized because the payload is not + a structure or a union type. + + Args: + input: + An instance of `StreamingTraitsInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `StreamingTraitsOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=STREAMING_TRAITS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def streaming_traits_require_length( + self, + input: StreamingTraitsRequireLengthInput, + plugins: list[Plugin] | None = None, + ) -> StreamingTraitsRequireLengthOutput: + """ + This examples serializes a streaming blob shape with a required content + length in the request body. In this example, no JSON document is + synthesized because the payload is not a structure or a union type. + + Args: + input: + An instance of `StreamingTraitsRequireLengthInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `StreamingTraitsRequireLengthOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=STREAMING_TRAITS_REQUIRE_LENGTH, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def streaming_traits_with_media_type( + self, + input: StreamingTraitsWithMediaTypeInput, + plugins: list[Plugin] | None = None, + ) -> StreamingTraitsWithMediaTypeOutput: + """ + This examples serializes a streaming media-typed blob shape in the + request body. This examples uses a `@mediaType` trait on the payload + to force a custom content-type to be serialized. + + Args: + input: + An instance of `StreamingTraitsWithMediaTypeInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `StreamingTraitsWithMediaTypeOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=STREAMING_TRAITS_WITH_MEDIA_TYPE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def test_body_structure( + self, input: TestBodyStructureInput, plugins: list[Plugin] | None = None + ) -> TestBodyStructureOutput: + """ + This example operation serializes a structure in the HTTP body. It + should ensure Content-Type: application/json is used in all requests and + that an \"empty\" body is an empty JSON document ({}). + + Args: + input: + An instance of `TestBodyStructureInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `TestBodyStructureOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=TEST_BODY_STRUCTURE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def test_get_no_input_no_payload( + self, input: TestGetNoInputNoPayloadInput, plugins: list[Plugin] | None = None + ) -> TestGetNoInputNoPayloadOutput: + """ + This example GET operation has no input and serializes a request without + a HTTP body. These tests are to ensure we do not attach a body or + related headers (Content-Length, Content-Type) to operations that + semantically cannot produce an HTTP body. + + Args: + input: + An instance of `TestGetNoInputNoPayloadInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `TestGetNoInputNoPayloadOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=TEST_GET_NO_INPUT_NO_PAYLOAD, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def test_get_no_payload( + self, input: TestGetNoPayloadInput, plugins: list[Plugin] | None = None + ) -> TestGetNoPayloadOutput: + """ + This example GET operation serializes a request without a modeled HTTP + body. These tests are to ensure we do not attach a body or related + headers (Content-Length, Content-Type) to operations that semantically + cannot produce an HTTP body. + + Args: + input: + An instance of `TestGetNoPayloadInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `TestGetNoPayloadOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=TEST_GET_NO_PAYLOAD, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def test_payload_blob( + self, input: TestPayloadBlobInput, plugins: list[Plugin] | None = None + ) -> TestPayloadBlobOutput: + """ + This example operation serializes a payload targeting a blob. The Blob + shape is not structured content and we cannot make assumptions about + what data will be sent. This test ensures only a generic \"Content-Type: + application/octet-stream\" header is used, and that we are not treating + an empty body as an empty JSON document. + + Args: + input: + An instance of `TestPayloadBlobInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `TestPayloadBlobOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=TEST_PAYLOAD_BLOB, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def test_payload_structure( + self, input: TestPayloadStructureInput, plugins: list[Plugin] | None = None + ) -> TestPayloadStructureOutput: + """ + This example operation serializes a payload targeting a structure. This + enforces the same requirements as TestBodyStructure but with the body + specified by the @httpPayload trait. + + Args: + input: + An instance of `TestPayloadStructureInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `TestPayloadStructureOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=TEST_PAYLOAD_STRUCTURE, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def test_post_no_input_no_payload( + self, input: TestPostNoInputNoPayloadInput, plugins: list[Plugin] | None = None + ) -> TestPostNoInputNoPayloadOutput: + """ + This example POST operation has no input and serializes a request + without a HTTP body. These tests are to ensure we do not attach a body + or related headers (Content-Type) to a POST operation with no modeled + input. + + Args: + input: + An instance of `TestPostNoInputNoPayloadInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `TestPostNoInputNoPayloadOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=TEST_POST_NO_INPUT_NO_PAYLOAD, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def test_post_no_payload( + self, input: TestPostNoPayloadInput, plugins: list[Plugin] | None = None + ) -> TestPostNoPayloadOutput: + """ + This example POST operation serializes a request without a modeled HTTP + body. These tests are to ensure we do not attach a body or related + headers (Content-Type) to a POST operation with no modeled payload. + + Args: + input: + An instance of `TestPostNoPayloadInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `TestPostNoPayloadOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=TEST_POST_NO_PAYLOAD, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def timestamp_format_headers( + self, input: TimestampFormatHeadersInput, plugins: list[Plugin] | None = None + ) -> TimestampFormatHeadersOutput: + """ + This example tests how timestamp request and response headers are + serialized. + + Args: + input: + An instance of `TimestampFormatHeadersInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `TimestampFormatHeadersOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=TIMESTAMP_FORMAT_HEADERS, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) + + async def unit_input_and_output( + self, input: UnitInputAndOutputInput, plugins: list[Plugin] | None = None + ) -> UnitInputAndOutputOutput: + """ + This test is similar to NoInputAndNoOutput, but uses explicit Unit + types. + + Args: + input: + An instance of `UnitInputAndOutputInput`. + plugins: + A list of callables that modify the configuration dynamically. + Changes made by these plugins only apply for the duration of the + operation execution and will not affect any other operation + invocations. + + Returns: + An instance of `UnitInputAndOutputOutput`. + """ + if self._closed: + raise RuntimeError( + "Cannot invoke an operation on a client that has been closed." + ) + + operation_plugins: list[Plugin] = [] + if plugins: + operation_plugins.extend(plugins) + await self._ensure_setup() + assert self._config is not None + if operation_plugins: + # Keep operation-plugin mutations scoped to this call. + config = deepcopy(self._config) + for plugin in operation_plugins: + plugin(config) + else: + config = self._config + if ( + config.protocol is None + or config.transport is None + or config.endpoint_resolver is None + or config.auth_scheme_resolver is None + or config.auth_schemes is None + ): + raise ExpectationNotMetError( + "protocol, transport, endpoint_resolver, auth_scheme_resolver," + " and auth_schemes MUST be set on the config to make calls." + ) + + retry_strategy = await self._retry_strategy_resolver.resolve_retry_strategy( + retry_strategy=config.retry_strategy, + retry_mode=config.retry_mode, + max_attempts=config.max_attempts, + ) + + pipeline = RequestPipeline(protocol=config.protocol, transport=config.transport) + call = ClientCall( + input=input, + operation=UNIT_INPUT_AND_OUTPUT, + context=TypedProperties({"config": config}), + interceptor=InterceptorChain(config.interceptors), + auth_scheme_resolver=config.auth_scheme_resolver, + supported_auth_schemes=config.auth_schemes, + endpoint_resolver=config.endpoint_resolver, + retry_strategy=retry_strategy, + ) + + return await pipeline(call) diff --git a/codegen-output/rest-json-1/src/restjson/config.py b/codegen-output/rest-json-1/src/restjson/config.py new file mode 100644 index 000000000..8d5c458e1 --- /dev/null +++ b/codegen-output/rest-json-1/src/restjson/config.py @@ -0,0 +1,674 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from dataclasses import dataclass, field +from typing import Any, Callable, ClassVar, Self, TypeAlias, Union, Unpack + +from smithy_aws_core.aio.protocols import RestJsonClientProtocol +from smithy_aws_core.auth import SigV4AuthScheme +from smithy_aws_core.config import AwsConfigOverrides, FileSystem +from smithy_aws_core.config.aws_config import AsyncAwsConfig +from smithy_aws_core.config.resolvers import EndpointUriResolver +from smithy_aws_core.config.types import FieldSpec +from smithy_aws_core.endpoints.standard_regional import ( + StandardRegionalEndpointsResolver, +) +from smithy_aws_core.identity import AWSCredentialsIdentity, AWSIdentityProperties +from smithy_core.aio.interfaces import ClientProtocol, EndpointResolver +from smithy_core.aio.interfaces.auth import AuthScheme +from smithy_core.aio.interfaces.identity import IdentityResolver +from smithy_core.interceptors import Interceptor +from smithy_core.shapes import ShapeID +from smithy_http.aio.aiohttp import AIOHTTPClient + +from ._private.schemas import REST_JSON as _SCHEMA_REST_JSON +from .auth import HTTPAuthSchemeResolver +from .models import ( + AllQueryStringTypesInput, + AllQueryStringTypesOutput, + ConstantAndVariableQueryStringInput, + ConstantAndVariableQueryStringOutput, + ConstantQueryStringInput, + ConstantQueryStringOutput, + ContentTypeParametersInput, + ContentTypeParametersOutput, + DatetimeOffsetsInput, + DatetimeOffsetsOutput, + DocumentTypeAsMapValueInput, + DocumentTypeAsMapValueOutput, + DocumentTypeAsPayloadInput, + DocumentTypeAsPayloadOutput, + DocumentTypeInput, + DocumentTypeOutput, + DuplexStreamInput, + DuplexStreamOutput, + DuplexStreamWithDistinctStreamsInput, + DuplexStreamWithDistinctStreamsOutput, + DuplexStreamWithInitialMessagesInput, + DuplexStreamWithInitialMessagesOutput, + EmptyInputAndEmptyOutputInput, + EmptyInputAndEmptyOutputOutput, + EndpointOperationInput, + EndpointOperationOutput, + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + FractionalSecondsInput, + FractionalSecondsOutput, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HostWithPathOperationInput, + HostWithPathOperationOutput, + HttpChecksumRequiredInput, + HttpChecksumRequiredOutput, + HttpEmptyPrefixHeadersInput, + HttpEmptyPrefixHeadersOutput, + HttpEnumPayloadInput, + HttpEnumPayloadOutput, + HttpPayloadTraitsInput, + HttpPayloadTraitsOutput, + HttpPayloadTraitsWithMediaTypeInput, + HttpPayloadTraitsWithMediaTypeOutput, + HttpPayloadWithStructureInput, + HttpPayloadWithStructureOutput, + HttpPayloadWithUnionInput, + HttpPayloadWithUnionOutput, + HttpPrefixHeadersInResponseInput, + HttpPrefixHeadersInResponseOutput, + HttpPrefixHeadersInput, + HttpPrefixHeadersOutput, + HttpQueryParamsOnlyOperationInput, + HttpQueryParamsOnlyOperationOutput, + HttpRequestWithFloatLabelsInput, + HttpRequestWithFloatLabelsOutput, + HttpRequestWithGreedyLabelInPathInput, + HttpRequestWithGreedyLabelInPathOutput, + HttpRequestWithLabelsAndTimestampFormatInput, + HttpRequestWithLabelsAndTimestampFormatOutput, + HttpRequestWithLabelsInput, + HttpRequestWithLabelsOutput, + HttpRequestWithRegexLiteralInput, + HttpRequestWithRegexLiteralOutput, + HttpResponseCodeInput, + HttpResponseCodeOutput, + HttpStringPayloadInput, + HttpStringPayloadOutput, + IgnoreQueryParamsInResponseInput, + IgnoreQueryParamsInResponseOutput, + InputAndOutputWithHeadersInput, + InputAndOutputWithHeadersOutput, + InputStreamInput, + InputStreamOutput, + InputStreamWithInitialRequestInput, + InputStreamWithInitialRequestOutput, + JsonBlobsInput, + JsonBlobsOutput, + JsonEnumsInput, + JsonEnumsOutput, + JsonIntEnumsInput, + JsonIntEnumsOutput, + JsonListsInput, + JsonListsOutput, + JsonMapsInput, + JsonMapsOutput, + JsonTimestampsInput, + JsonTimestampsOutput, + JsonUnionsInput, + JsonUnionsOutput, + MalformedAcceptWithBodyInput, + MalformedAcceptWithBodyOutput, + MalformedAcceptWithGenericStringInput, + MalformedAcceptWithGenericStringOutput, + MalformedAcceptWithPayloadInput, + MalformedAcceptWithPayloadOutput, + MalformedBlobInput, + MalformedBlobOutput, + MalformedBooleanInput, + MalformedBooleanOutput, + MalformedByteInput, + MalformedByteOutput, + MalformedContentTypeWithBodyInput, + MalformedContentTypeWithBodyOutput, + MalformedContentTypeWithGenericStringInput, + MalformedContentTypeWithGenericStringOutput, + MalformedContentTypeWithPayloadInput, + MalformedContentTypeWithPayloadOutput, + MalformedContentTypeWithoutBodyEmptyInputInput, + MalformedContentTypeWithoutBodyEmptyInputOutput, + MalformedContentTypeWithoutBodyInput, + MalformedContentTypeWithoutBodyOutput, + MalformedDoubleInput, + MalformedDoubleOutput, + MalformedFloatInput, + MalformedFloatOutput, + MalformedIntegerInput, + MalformedIntegerOutput, + MalformedListInput, + MalformedListOutput, + MalformedLongInput, + MalformedLongOutput, + MalformedMapInput, + MalformedMapOutput, + MalformedRequestBodyInput, + MalformedRequestBodyOutput, + MalformedShortInput, + MalformedShortOutput, + MalformedStringInput, + MalformedStringOutput, + MalformedTimestampBodyDateTimeInput, + MalformedTimestampBodyDateTimeOutput, + MalformedTimestampBodyDefaultInput, + MalformedTimestampBodyDefaultOutput, + MalformedTimestampBodyHttpDateInput, + MalformedTimestampBodyHttpDateOutput, + MalformedTimestampHeaderDateTimeInput, + MalformedTimestampHeaderDateTimeOutput, + MalformedTimestampHeaderDefaultInput, + MalformedTimestampHeaderDefaultOutput, + MalformedTimestampHeaderEpochInput, + MalformedTimestampHeaderEpochOutput, + MalformedTimestampPathDefaultInput, + MalformedTimestampPathDefaultOutput, + MalformedTimestampPathEpochInput, + MalformedTimestampPathEpochOutput, + MalformedTimestampPathHttpDateInput, + MalformedTimestampPathHttpDateOutput, + MalformedTimestampQueryDefaultInput, + MalformedTimestampQueryDefaultOutput, + MalformedTimestampQueryEpochInput, + MalformedTimestampQueryEpochOutput, + MalformedTimestampQueryHttpDateInput, + MalformedTimestampQueryHttpDateOutput, + MalformedUnionInput, + MalformedUnionOutput, + MediaTypeHeaderInput, + MediaTypeHeaderOutput, + NoInputAndNoOutputInput, + NoInputAndNoOutputOutput, + NoInputAndOutputInput, + NoInputAndOutputOutput, + NullAndEmptyHeadersClientInput, + NullAndEmptyHeadersClientOutput, + NullAndEmptyHeadersServerInput, + NullAndEmptyHeadersServerOutput, + OmitsNullSerializesEmptyStringInput, + OmitsNullSerializesEmptyStringOutput, + OmitsSerializingEmptyListsInput, + OmitsSerializingEmptyListsOutput, + OperationWithDefaultsInput, + OperationWithDefaultsOutput, + OperationWithNestedStructureInput, + OperationWithNestedStructureOutput, + OutputStreamInput, + OutputStreamOutput, + OutputStreamWithInitialResponseInput, + OutputStreamWithInitialResponseOutput, + PostPlayerActionInput, + PostPlayerActionOutput, + PostUnionWithJsonNameInput, + PostUnionWithJsonNameOutput, + PutWithContentEncodingInput, + PutWithContentEncodingOutput, + QueryIdempotencyTokenAutoFillInput, + QueryIdempotencyTokenAutoFillOutput, + QueryParamsAsStringListMapInput, + QueryParamsAsStringListMapOutput, + QueryPrecedenceInput, + QueryPrecedenceOutput, + RecursiveShapesInput, + RecursiveShapesOutput, + ResponseCodeHttpFallbackInput, + ResponseCodeHttpFallbackOutput, + ResponseCodeRequiredInput, + ResponseCodeRequiredOutput, + SimpleScalarPropertiesInput, + SimpleScalarPropertiesOutput, + SparseJsonListsInput, + SparseJsonListsOutput, + SparseJsonMapsInput, + SparseJsonMapsOutput, + StreamingTraitsInput, + StreamingTraitsOutput, + StreamingTraitsRequireLengthInput, + StreamingTraitsRequireLengthOutput, + StreamingTraitsWithMediaTypeInput, + StreamingTraitsWithMediaTypeOutput, + TestBodyStructureInput, + TestBodyStructureOutput, + TestGetNoInputNoPayloadInput, + TestGetNoInputNoPayloadOutput, + TestGetNoPayloadInput, + TestGetNoPayloadOutput, + TestPayloadBlobInput, + TestPayloadBlobOutput, + TestPayloadStructureInput, + TestPayloadStructureOutput, + TestPostNoInputNoPayloadInput, + TestPostNoInputNoPayloadOutput, + TestPostNoPayloadInput, + TestPostNoPayloadOutput, + TimestampFormatHeadersInput, + TimestampFormatHeadersOutput, + UnitInputAndOutputInput, + UnitInputAndOutputOutput, +) + + +_ServiceInterceptor = Union[ + Interceptor[AllQueryStringTypesInput, AllQueryStringTypesOutput, Any, Any], + Interceptor[ + ConstantAndVariableQueryStringInput, + ConstantAndVariableQueryStringOutput, + Any, + Any, + ], + Interceptor[ConstantQueryStringInput, ConstantQueryStringOutput, Any, Any], + Interceptor[ContentTypeParametersInput, ContentTypeParametersOutput, Any, Any], + Interceptor[DatetimeOffsetsInput, DatetimeOffsetsOutput, Any, Any], + Interceptor[DocumentTypeInput, DocumentTypeOutput, Any, Any], + Interceptor[DocumentTypeAsMapValueInput, DocumentTypeAsMapValueOutput, Any, Any], + Interceptor[DocumentTypeAsPayloadInput, DocumentTypeAsPayloadOutput, Any, Any], + Interceptor[DuplexStreamInput, DuplexStreamOutput, Any, Any], + Interceptor[ + DuplexStreamWithDistinctStreamsInput, + DuplexStreamWithDistinctStreamsOutput, + Any, + Any, + ], + Interceptor[ + DuplexStreamWithInitialMessagesInput, + DuplexStreamWithInitialMessagesOutput, + Any, + Any, + ], + Interceptor[ + EmptyInputAndEmptyOutputInput, EmptyInputAndEmptyOutputOutput, Any, Any + ], + Interceptor[EndpointOperationInput, EndpointOperationOutput, Any, Any], + Interceptor[ + EndpointWithHostLabelOperationInput, + EndpointWithHostLabelOperationOutput, + Any, + Any, + ], + Interceptor[FractionalSecondsInput, FractionalSecondsOutput, Any, Any], + Interceptor[GreetingWithErrorsInput, GreetingWithErrorsOutput, Any, Any], + Interceptor[HostWithPathOperationInput, HostWithPathOperationOutput, Any, Any], + Interceptor[HttpChecksumRequiredInput, HttpChecksumRequiredOutput, Any, Any], + Interceptor[HttpEmptyPrefixHeadersInput, HttpEmptyPrefixHeadersOutput, Any, Any], + Interceptor[HttpEnumPayloadInput, HttpEnumPayloadOutput, Any, Any], + Interceptor[HttpPayloadTraitsInput, HttpPayloadTraitsOutput, Any, Any], + Interceptor[ + HttpPayloadTraitsWithMediaTypeInput, + HttpPayloadTraitsWithMediaTypeOutput, + Any, + Any, + ], + Interceptor[ + HttpPayloadWithStructureInput, HttpPayloadWithStructureOutput, Any, Any + ], + Interceptor[HttpPayloadWithUnionInput, HttpPayloadWithUnionOutput, Any, Any], + Interceptor[HttpPrefixHeadersInput, HttpPrefixHeadersOutput, Any, Any], + Interceptor[ + HttpPrefixHeadersInResponseInput, HttpPrefixHeadersInResponseOutput, Any, Any + ], + Interceptor[ + HttpQueryParamsOnlyOperationInput, HttpQueryParamsOnlyOperationOutput, Any, Any + ], + Interceptor[ + HttpRequestWithFloatLabelsInput, HttpRequestWithFloatLabelsOutput, Any, Any + ], + Interceptor[ + HttpRequestWithGreedyLabelInPathInput, + HttpRequestWithGreedyLabelInPathOutput, + Any, + Any, + ], + Interceptor[HttpRequestWithLabelsInput, HttpRequestWithLabelsOutput, Any, Any], + Interceptor[ + HttpRequestWithLabelsAndTimestampFormatInput, + HttpRequestWithLabelsAndTimestampFormatOutput, + Any, + Any, + ], + Interceptor[ + HttpRequestWithRegexLiteralInput, HttpRequestWithRegexLiteralOutput, Any, Any + ], + Interceptor[HttpResponseCodeInput, HttpResponseCodeOutput, Any, Any], + Interceptor[HttpStringPayloadInput, HttpStringPayloadOutput, Any, Any], + Interceptor[ + IgnoreQueryParamsInResponseInput, IgnoreQueryParamsInResponseOutput, Any, Any + ], + Interceptor[ + InputAndOutputWithHeadersInput, InputAndOutputWithHeadersOutput, Any, Any + ], + Interceptor[InputStreamInput, InputStreamOutput, Any, Any], + Interceptor[ + InputStreamWithInitialRequestInput, + InputStreamWithInitialRequestOutput, + Any, + Any, + ], + Interceptor[JsonBlobsInput, JsonBlobsOutput, Any, Any], + Interceptor[JsonEnumsInput, JsonEnumsOutput, Any, Any], + Interceptor[JsonIntEnumsInput, JsonIntEnumsOutput, Any, Any], + Interceptor[JsonListsInput, JsonListsOutput, Any, Any], + Interceptor[JsonMapsInput, JsonMapsOutput, Any, Any], + Interceptor[JsonTimestampsInput, JsonTimestampsOutput, Any, Any], + Interceptor[JsonUnionsInput, JsonUnionsOutput, Any, Any], + Interceptor[MalformedAcceptWithBodyInput, MalformedAcceptWithBodyOutput, Any, Any], + Interceptor[ + MalformedAcceptWithGenericStringInput, + MalformedAcceptWithGenericStringOutput, + Any, + Any, + ], + Interceptor[ + MalformedAcceptWithPayloadInput, MalformedAcceptWithPayloadOutput, Any, Any + ], + Interceptor[MalformedBlobInput, MalformedBlobOutput, Any, Any], + Interceptor[MalformedBooleanInput, MalformedBooleanOutput, Any, Any], + Interceptor[MalformedByteInput, MalformedByteOutput, Any, Any], + Interceptor[ + MalformedContentTypeWithBodyInput, MalformedContentTypeWithBodyOutput, Any, Any + ], + Interceptor[ + MalformedContentTypeWithGenericStringInput, + MalformedContentTypeWithGenericStringOutput, + Any, + Any, + ], + Interceptor[ + MalformedContentTypeWithoutBodyInput, + MalformedContentTypeWithoutBodyOutput, + Any, + Any, + ], + Interceptor[ + MalformedContentTypeWithoutBodyEmptyInputInput, + MalformedContentTypeWithoutBodyEmptyInputOutput, + Any, + Any, + ], + Interceptor[ + MalformedContentTypeWithPayloadInput, + MalformedContentTypeWithPayloadOutput, + Any, + Any, + ], + Interceptor[MalformedDoubleInput, MalformedDoubleOutput, Any, Any], + Interceptor[MalformedFloatInput, MalformedFloatOutput, Any, Any], + Interceptor[MalformedIntegerInput, MalformedIntegerOutput, Any, Any], + Interceptor[MalformedListInput, MalformedListOutput, Any, Any], + Interceptor[MalformedLongInput, MalformedLongOutput, Any, Any], + Interceptor[MalformedMapInput, MalformedMapOutput, Any, Any], + Interceptor[MalformedRequestBodyInput, MalformedRequestBodyOutput, Any, Any], + Interceptor[MalformedShortInput, MalformedShortOutput, Any, Any], + Interceptor[MalformedStringInput, MalformedStringOutput, Any, Any], + Interceptor[ + MalformedTimestampBodyDateTimeInput, + MalformedTimestampBodyDateTimeOutput, + Any, + Any, + ], + Interceptor[ + MalformedTimestampBodyDefaultInput, + MalformedTimestampBodyDefaultOutput, + Any, + Any, + ], + Interceptor[ + MalformedTimestampBodyHttpDateInput, + MalformedTimestampBodyHttpDateOutput, + Any, + Any, + ], + Interceptor[ + MalformedTimestampHeaderDateTimeInput, + MalformedTimestampHeaderDateTimeOutput, + Any, + Any, + ], + Interceptor[ + MalformedTimestampHeaderDefaultInput, + MalformedTimestampHeaderDefaultOutput, + Any, + Any, + ], + Interceptor[ + MalformedTimestampHeaderEpochInput, + MalformedTimestampHeaderEpochOutput, + Any, + Any, + ], + Interceptor[ + MalformedTimestampPathDefaultInput, + MalformedTimestampPathDefaultOutput, + Any, + Any, + ], + Interceptor[ + MalformedTimestampPathEpochInput, MalformedTimestampPathEpochOutput, Any, Any + ], + Interceptor[ + MalformedTimestampPathHttpDateInput, + MalformedTimestampPathHttpDateOutput, + Any, + Any, + ], + Interceptor[ + MalformedTimestampQueryDefaultInput, + MalformedTimestampQueryDefaultOutput, + Any, + Any, + ], + Interceptor[ + MalformedTimestampQueryEpochInput, MalformedTimestampQueryEpochOutput, Any, Any + ], + Interceptor[ + MalformedTimestampQueryHttpDateInput, + MalformedTimestampQueryHttpDateOutput, + Any, + Any, + ], + Interceptor[MalformedUnionInput, MalformedUnionOutput, Any, Any], + Interceptor[MediaTypeHeaderInput, MediaTypeHeaderOutput, Any, Any], + Interceptor[NoInputAndNoOutputInput, NoInputAndNoOutputOutput, Any, Any], + Interceptor[NoInputAndOutputInput, NoInputAndOutputOutput, Any, Any], + Interceptor[ + NullAndEmptyHeadersClientInput, NullAndEmptyHeadersClientOutput, Any, Any + ], + Interceptor[ + NullAndEmptyHeadersServerInput, NullAndEmptyHeadersServerOutput, Any, Any + ], + Interceptor[ + OmitsNullSerializesEmptyStringInput, + OmitsNullSerializesEmptyStringOutput, + Any, + Any, + ], + Interceptor[ + OmitsSerializingEmptyListsInput, OmitsSerializingEmptyListsOutput, Any, Any + ], + Interceptor[OperationWithDefaultsInput, OperationWithDefaultsOutput, Any, Any], + Interceptor[ + OperationWithNestedStructureInput, OperationWithNestedStructureOutput, Any, Any + ], + Interceptor[OutputStreamInput, OutputStreamOutput, Any, Any], + Interceptor[ + OutputStreamWithInitialResponseInput, + OutputStreamWithInitialResponseOutput, + Any, + Any, + ], + Interceptor[PostPlayerActionInput, PostPlayerActionOutput, Any, Any], + Interceptor[PostUnionWithJsonNameInput, PostUnionWithJsonNameOutput, Any, Any], + Interceptor[PutWithContentEncodingInput, PutWithContentEncodingOutput, Any, Any], + Interceptor[ + QueryIdempotencyTokenAutoFillInput, + QueryIdempotencyTokenAutoFillOutput, + Any, + Any, + ], + Interceptor[ + QueryParamsAsStringListMapInput, QueryParamsAsStringListMapOutput, Any, Any + ], + Interceptor[QueryPrecedenceInput, QueryPrecedenceOutput, Any, Any], + Interceptor[RecursiveShapesInput, RecursiveShapesOutput, Any, Any], + Interceptor[ + ResponseCodeHttpFallbackInput, ResponseCodeHttpFallbackOutput, Any, Any + ], + Interceptor[ResponseCodeRequiredInput, ResponseCodeRequiredOutput, Any, Any], + Interceptor[SimpleScalarPropertiesInput, SimpleScalarPropertiesOutput, Any, Any], + Interceptor[SparseJsonListsInput, SparseJsonListsOutput, Any, Any], + Interceptor[SparseJsonMapsInput, SparseJsonMapsOutput, Any, Any], + Interceptor[StreamingTraitsInput, StreamingTraitsOutput, Any, Any], + Interceptor[ + StreamingTraitsRequireLengthInput, StreamingTraitsRequireLengthOutput, Any, Any + ], + Interceptor[ + StreamingTraitsWithMediaTypeInput, StreamingTraitsWithMediaTypeOutput, Any, Any + ], + Interceptor[TestBodyStructureInput, TestBodyStructureOutput, Any, Any], + Interceptor[TestGetNoInputNoPayloadInput, TestGetNoInputNoPayloadOutput, Any, Any], + Interceptor[TestGetNoPayloadInput, TestGetNoPayloadOutput, Any, Any], + Interceptor[TestPayloadBlobInput, TestPayloadBlobOutput, Any, Any], + Interceptor[TestPayloadStructureInput, TestPayloadStructureOutput, Any, Any], + Interceptor[ + TestPostNoInputNoPayloadInput, TestPostNoInputNoPayloadOutput, Any, Any + ], + Interceptor[TestPostNoPayloadInput, TestPostNoPayloadOutput, Any, Any], + Interceptor[TimestampFormatHeadersInput, TimestampFormatHeadersOutput, Any, Any], + Interceptor[UnitInputAndOutputInput, UnitInputAndOutputOutput, Any, Any], +] + + +class _AsyncRestJsonProtocolConfigOverrides(AwsConfigOverrides, total=False): + endpoint_resolver: EndpointResolver | None + protocol: ClientProtocol[Any, Any] | None + auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None + auth_scheme_resolver: HTTPAuthSchemeResolver | None + + +@dataclass(kw_only=True, repr=False, init=False) +class AsyncRestJsonProtocolConfig(AsyncAwsConfig): + """Rest Json Protocol configuration (async-resolved).""" + + endpoint_resolver: EndpointResolver | None = None + """ + The endpoint resolver used to resolve the final endpoint per-operation + based on the configuration. + """ + + protocol: ClientProtocol[Any, Any] | None = None + """The protocol to serialize and deserialize requests with.""" + + interceptors: list[_ServiceInterceptor] = field(default_factory=lambda: []) + """ + The list of interceptors, which are hooks that are called during the + execution of a request. + """ + + auth_schemes: dict[ShapeID, AuthScheme[Any, Any, Any, Any]] | None = None + """A map of auth scheme ids to auth schemes.""" + + auth_scheme_resolver: HTTPAuthSchemeResolver | None = None + """ + An auth scheme resolver that determines the auth scheme for each + operation. + """ + + aws_credentials_identity_resolver: ( + IdentityResolver[AWSCredentialsIdentity, AWSIdentityProperties] | None + ) = None + """Resolves AWS Credentials. Required for operations that use Sigv4 Auth.""" + + region: str | None = None + """ + The AWS region to connect to. The configured region is used to determine + the service endpoint. + """ + + aws_access_key_id: str | None = None + """The identifier for a secret access key.""" + + aws_secret_access_key: str | None = None + """A secret access key that can be used to sign requests.""" + + aws_session_token: str | None = None + """The session token used with temporary AWS credentials.""" + + user_agent_extra: str | None = None + """Additional suffix to be added to the User-Agent header.""" + + sdk_ua_app_id: str | None = None + """ + A unique and opaque application ID that is appended to the User-Agent + header. + """ + + _FIELDS: ClassVar[dict[str, FieldSpec]] = { + "aws_credentials_identity_resolver": FieldSpec(default=None), + "region": FieldSpec(default=None), + "aws_access_key_id": FieldSpec(default=None), + "aws_secret_access_key": FieldSpec(default=None), + "aws_session_token": FieldSpec(default=None), + "user_agent_extra": FieldSpec(default=None), + "sdk_ua_app_id": FieldSpec(default=None), + **AsyncAwsConfig._FIELDS, + "endpoint_uri": FieldSpec( + default=None, resolver=EndpointUriResolver("rest_json_protocol") + ), + "endpoint_resolver": FieldSpec( + default_factory=lambda: StandardRegionalEndpointsResolver( + endpoint_prefix="restjson" + ) + ), + "protocol": FieldSpec( + default_factory=lambda: RestJsonClientProtocol(_SCHEMA_REST_JSON) + ), + "auth_schemes": FieldSpec( + default_factory=lambda: { + ShapeID("aws.auth#sigv4"): SigV4AuthScheme(service="restjson") + } + ), + "auth_scheme_resolver": FieldSpec(default_factory=HTTPAuthSchemeResolver), + "transport": FieldSpec(default_factory=lambda: AIOHTTPClient()), + } + + def set_auth_scheme(self, scheme: AuthScheme[Any, Any, Any, Any]) -> None: + """ + Set an auth scheme implementation using its scheme ID. :param scheme: + The auth scheme to add or replace. + """ + auth_schemes = dict(self.auth_schemes or {}) + auth_schemes[scheme.scheme_id] = scheme + self.auth_schemes = auth_schemes + + @classmethod + async def resolve( # pyright: ignore[reportIncompatibleMethodOverride] + cls, + *, + profile: str | None = None, + fs: FileSystem | None = None, + config_file_path: str | None = None, + credentials_file_path: str | None = None, + **overrides: Unpack[_AsyncRestJsonProtocolConfigOverrides], + ) -> Self: + """ + Resolve config from environment, config files, defaults, and explicit + overrides. + """ + return await cls._resolve( + profile=profile, + fs=fs, + config_file_path=config_file_path, + credentials_file_path=credentials_file_path, + overrides=overrides, + ) + + +Plugin: TypeAlias = Callable[[AsyncRestJsonProtocolConfig], None] +""" +A callable that customizes a client configuration. Service-level plugins +are applied once to the base configuration inherited by every operation. +Operation-level plugins apply only to a single operation invocation. +""" diff --git a/codegen-output/rest-json-1/src/restjson/models.py b/codegen-output/rest-json-1/src/restjson/models.py new file mode 100644 index 000000000..5dce1cdb9 --- /dev/null +++ b/codegen-output/rest-json-1/src/restjson/models.py @@ -0,0 +1,17038 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from base64 import b64decode +from dataclasses import dataclass, field +from datetime import datetime, timezone +from enum import IntEnum, StrEnum +import logging +from typing import Any, Literal, Self, Union + +from smithy_core.aio.interfaces import StreamingBlob +from smithy_core.deserializers import ShapeDeserializer +from smithy_core.documents import Document, TypeRegistry +from smithy_core.exceptions import ModeledError, SerializationError +from smithy_core.prelude import UNIT as _SCHEMA_UNIT +from smithy_core.schemas import APIOperation, Schema +from smithy_core.serializers import ShapeSerializer +from smithy_core.shapes import ShapeID +from smithy_core.types import JsonString, UnknownEnumMixin + +from ._private.schemas import ( + ALL_QUERY_STRING_TYPES as _SCHEMA_ALL_QUERY_STRING_TYPES, + ALL_QUERY_STRING_TYPES_INPUT as _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT, + ALL_QUERY_STRING_TYPES_OUTPUT as _SCHEMA_ALL_QUERY_STRING_TYPES_OUTPUT, + BLOB_PAYLOAD_EVENT as _SCHEMA_BLOB_PAYLOAD_EVENT, + CLIENT_OPTIONAL_DEFAULTS as _SCHEMA_CLIENT_OPTIONAL_DEFAULTS, + COMPLEX_ERROR as _SCHEMA_COMPLEX_ERROR, + COMPLEX_NESTED_ERROR_DATA as _SCHEMA_COMPLEX_NESTED_ERROR_DATA, + CONSTANT_AND_VARIABLE_QUERY_STRING as _SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING, + CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT as _SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT, + CONSTANT_AND_VARIABLE_QUERY_STRING_OUTPUT as _SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_OUTPUT, + CONSTANT_QUERY_STRING as _SCHEMA_CONSTANT_QUERY_STRING, + CONSTANT_QUERY_STRING_INPUT as _SCHEMA_CONSTANT_QUERY_STRING_INPUT, + CONSTANT_QUERY_STRING_OUTPUT as _SCHEMA_CONSTANT_QUERY_STRING_OUTPUT, + CONTENT_TYPE_PARAMETERS as _SCHEMA_CONTENT_TYPE_PARAMETERS, + CONTENT_TYPE_PARAMETERS_INPUT as _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, + CONTENT_TYPE_PARAMETERS_OUTPUT as _SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, + DATETIME_OFFSETS as _SCHEMA_DATETIME_OFFSETS, + DATETIME_OFFSETS_INPUT as _SCHEMA_DATETIME_OFFSETS_INPUT, + DATETIME_OFFSETS_OUTPUT as _SCHEMA_DATETIME_OFFSETS_OUTPUT, + DEFAULTS as _SCHEMA_DEFAULTS, + DIALOG as _SCHEMA_DIALOG, + DOCUMENT_TYPE as _SCHEMA_DOCUMENT_TYPE, + DOCUMENT_TYPE_AS_MAP_VALUE as _SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE, + DOCUMENT_TYPE_AS_MAP_VALUE_INPUT as _SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_INPUT, + DOCUMENT_TYPE_AS_MAP_VALUE_OUTPUT as _SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_OUTPUT, + DOCUMENT_TYPE_AS_PAYLOAD as _SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD, + DOCUMENT_TYPE_AS_PAYLOAD_INPUT as _SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_INPUT, + DOCUMENT_TYPE_AS_PAYLOAD_OUTPUT as _SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_OUTPUT, + DOCUMENT_TYPE_INPUT as _SCHEMA_DOCUMENT_TYPE_INPUT, + DOCUMENT_TYPE_OUTPUT as _SCHEMA_DOCUMENT_TYPE_OUTPUT, + DUPLEX_STREAM as _SCHEMA_DUPLEX_STREAM, + DUPLEX_STREAM_INPUT as _SCHEMA_DUPLEX_STREAM_INPUT, + DUPLEX_STREAM_OUTPUT as _SCHEMA_DUPLEX_STREAM_OUTPUT, + DUPLEX_STREAM_WITH_DISTINCT_STREAMS as _SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS, + DUPLEX_STREAM_WITH_DISTINCT_STREAMS_INPUT as _SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS_INPUT, + DUPLEX_STREAM_WITH_DISTINCT_STREAMS_OUTPUT as _SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS_OUTPUT, + DUPLEX_STREAM_WITH_INITIAL_MESSAGES as _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES, + DUPLEX_STREAM_WITH_INITIAL_MESSAGES_INPUT as _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_INPUT, + DUPLEX_STREAM_WITH_INITIAL_MESSAGES_OUTPUT as _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_OUTPUT, + EMPTY_INPUT_AND_EMPTY_OUTPUT as _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT, + EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT as _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, + EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT as _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, + ENDPOINT_OPERATION as _SCHEMA_ENDPOINT_OPERATION, + ENDPOINT_OPERATION_INPUT as _SCHEMA_ENDPOINT_OPERATION_INPUT, + ENDPOINT_OPERATION_OUTPUT as _SCHEMA_ENDPOINT_OPERATION_OUTPUT, + ENDPOINT_WITH_HOST_LABEL_OPERATION as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION, + ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, + ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT as _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, + ERROR_EVENT as _SCHEMA_ERROR_EVENT, + EVENT_STREAM as _SCHEMA_EVENT_STREAM, + FAREWELL as _SCHEMA_FAREWELL, + FOO_ERROR as _SCHEMA_FOO_ERROR, + FRACTIONAL_SECONDS as _SCHEMA_FRACTIONAL_SECONDS, + FRACTIONAL_SECONDS_INPUT as _SCHEMA_FRACTIONAL_SECONDS_INPUT, + FRACTIONAL_SECONDS_OUTPUT as _SCHEMA_FRACTIONAL_SECONDS_OUTPUT, + GREETING_STRUCT as _SCHEMA_GREETING_STRUCT, + GREETING_WITH_ERRORS as _SCHEMA_GREETING_WITH_ERRORS, + GREETING_WITH_ERRORS_INPUT as _SCHEMA_GREETING_WITH_ERRORS_INPUT, + GREETING_WITH_ERRORS_OUTPUT as _SCHEMA_GREETING_WITH_ERRORS_OUTPUT, + HEADERS_AND_EXPLICIT_PAYLOAD_EVENT as _SCHEMA_HEADERS_AND_EXPLICIT_PAYLOAD_EVENT, + HEADERS_AND_IMPLICIT_PAYLOAD_EVENT as _SCHEMA_HEADERS_AND_IMPLICIT_PAYLOAD_EVENT, + HEADERS_EVENT as _SCHEMA_HEADERS_EVENT, + HOST_WITH_PATH_OPERATION as _SCHEMA_HOST_WITH_PATH_OPERATION, + HOST_WITH_PATH_OPERATION_INPUT as _SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, + HOST_WITH_PATH_OPERATION_OUTPUT as _SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, + HTTP_CHECKSUM_REQUIRED as _SCHEMA_HTTP_CHECKSUM_REQUIRED, + HTTP_CHECKSUM_REQUIRED_INPUT as _SCHEMA_HTTP_CHECKSUM_REQUIRED_INPUT, + HTTP_CHECKSUM_REQUIRED_OUTPUT as _SCHEMA_HTTP_CHECKSUM_REQUIRED_OUTPUT, + HTTP_EMPTY_PREFIX_HEADERS as _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS, + HTTP_EMPTY_PREFIX_HEADERS_INPUT as _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_INPUT, + HTTP_EMPTY_PREFIX_HEADERS_OUTPUT as _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_OUTPUT, + HTTP_ENUM_PAYLOAD as _SCHEMA_HTTP_ENUM_PAYLOAD, + HTTP_ENUM_PAYLOAD_INPUT as _SCHEMA_HTTP_ENUM_PAYLOAD_INPUT, + HTTP_ENUM_PAYLOAD_OUTPUT as _SCHEMA_HTTP_ENUM_PAYLOAD_OUTPUT, + HTTP_PAYLOAD_TRAITS as _SCHEMA_HTTP_PAYLOAD_TRAITS, + HTTP_PAYLOAD_TRAITS_INPUT as _SCHEMA_HTTP_PAYLOAD_TRAITS_INPUT, + HTTP_PAYLOAD_TRAITS_OUTPUT as _SCHEMA_HTTP_PAYLOAD_TRAITS_OUTPUT, + HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE as _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE, + HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT as _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT, + HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT as _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT, + HTTP_PAYLOAD_WITH_STRUCTURE as _SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE, + HTTP_PAYLOAD_WITH_STRUCTURE_INPUT as _SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_INPUT, + HTTP_PAYLOAD_WITH_STRUCTURE_OUTPUT as _SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_OUTPUT, + HTTP_PAYLOAD_WITH_UNION as _SCHEMA_HTTP_PAYLOAD_WITH_UNION, + HTTP_PAYLOAD_WITH_UNION_INPUT as _SCHEMA_HTTP_PAYLOAD_WITH_UNION_INPUT, + HTTP_PAYLOAD_WITH_UNION_OUTPUT as _SCHEMA_HTTP_PAYLOAD_WITH_UNION_OUTPUT, + HTTP_PREFIX_HEADERS as _SCHEMA_HTTP_PREFIX_HEADERS, + HTTP_PREFIX_HEADERS_INPUT as _SCHEMA_HTTP_PREFIX_HEADERS_INPUT, + HTTP_PREFIX_HEADERS_IN_RESPONSE as _SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE, + HTTP_PREFIX_HEADERS_IN_RESPONSE_INPUT as _SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_INPUT, + HTTP_PREFIX_HEADERS_IN_RESPONSE_OUTPUT as _SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_OUTPUT, + HTTP_PREFIX_HEADERS_OUTPUT as _SCHEMA_HTTP_PREFIX_HEADERS_OUTPUT, + HTTP_QUERY_PARAMS_ONLY_OPERATION as _SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION, + HTTP_QUERY_PARAMS_ONLY_OPERATION_INPUT as _SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_INPUT, + HTTP_QUERY_PARAMS_ONLY_OPERATION_OUTPUT as _SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_OUTPUT, + HTTP_REQUEST_WITH_FLOAT_LABELS as _SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS, + HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT as _SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT, + HTTP_REQUEST_WITH_FLOAT_LABELS_OUTPUT as _SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_OUTPUT, + HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH as _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH, + HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT as _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT, + HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_OUTPUT as _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_OUTPUT, + HTTP_REQUEST_WITH_LABELS as _SCHEMA_HTTP_REQUEST_WITH_LABELS, + HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT as _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT, + HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT as _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT, + HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_OUTPUT as _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_OUTPUT, + HTTP_REQUEST_WITH_LABELS_INPUT as _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT, + HTTP_REQUEST_WITH_LABELS_OUTPUT as _SCHEMA_HTTP_REQUEST_WITH_LABELS_OUTPUT, + HTTP_REQUEST_WITH_REGEX_LITERAL as _SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL, + HTTP_REQUEST_WITH_REGEX_LITERAL_INPUT as _SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_INPUT, + HTTP_REQUEST_WITH_REGEX_LITERAL_OUTPUT as _SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_OUTPUT, + HTTP_RESPONSE_CODE as _SCHEMA_HTTP_RESPONSE_CODE, + HTTP_RESPONSE_CODE_INPUT as _SCHEMA_HTTP_RESPONSE_CODE_INPUT, + HTTP_RESPONSE_CODE_OUTPUT as _SCHEMA_HTTP_RESPONSE_CODE_OUTPUT, + HTTP_STRING_PAYLOAD as _SCHEMA_HTTP_STRING_PAYLOAD, + HTTP_STRING_PAYLOAD_INPUT as _SCHEMA_HTTP_STRING_PAYLOAD_INPUT, + HTTP_STRING_PAYLOAD_OUTPUT as _SCHEMA_HTTP_STRING_PAYLOAD_OUTPUT, + IGNORE_QUERY_PARAMS_IN_RESPONSE as _SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE, + IGNORE_QUERY_PARAMS_IN_RESPONSE_INPUT as _SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_INPUT, + IGNORE_QUERY_PARAMS_IN_RESPONSE_OUTPUT as _SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_OUTPUT, + INPUT_AND_OUTPUT_WITH_HEADERS as _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS, + INPUT_AND_OUTPUT_WITH_HEADERS_INPUT as _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT, + INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT as _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT, + INPUT_STREAM as _SCHEMA_INPUT_STREAM, + INPUT_STREAM_INPUT as _SCHEMA_INPUT_STREAM_INPUT, + INPUT_STREAM_OUTPUT as _SCHEMA_INPUT_STREAM_OUTPUT, + INPUT_STREAM_WITH_INITIAL_REQUEST as _SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST, + INPUT_STREAM_WITH_INITIAL_REQUEST_INPUT as _SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_INPUT, + INPUT_STREAM_WITH_INITIAL_REQUEST_OUTPUT as _SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_OUTPUT, + INVALID_GREETING as _SCHEMA_INVALID_GREETING, + JSON_BLOBS as _SCHEMA_JSON_BLOBS, + JSON_BLOBS_INPUT as _SCHEMA_JSON_BLOBS_INPUT, + JSON_BLOBS_OUTPUT as _SCHEMA_JSON_BLOBS_OUTPUT, + JSON_ENUMS as _SCHEMA_JSON_ENUMS, + JSON_ENUMS_INPUT as _SCHEMA_JSON_ENUMS_INPUT, + JSON_ENUMS_OUTPUT as _SCHEMA_JSON_ENUMS_OUTPUT, + JSON_INT_ENUMS as _SCHEMA_JSON_INT_ENUMS, + JSON_INT_ENUMS_INPUT as _SCHEMA_JSON_INT_ENUMS_INPUT, + JSON_INT_ENUMS_OUTPUT as _SCHEMA_JSON_INT_ENUMS_OUTPUT, + JSON_LISTS as _SCHEMA_JSON_LISTS, + JSON_LISTS_INPUT as _SCHEMA_JSON_LISTS_INPUT, + JSON_LISTS_OUTPUT as _SCHEMA_JSON_LISTS_OUTPUT, + JSON_MAPS as _SCHEMA_JSON_MAPS, + JSON_MAPS_INPUT as _SCHEMA_JSON_MAPS_INPUT, + JSON_MAPS_OUTPUT as _SCHEMA_JSON_MAPS_OUTPUT, + JSON_TIMESTAMPS as _SCHEMA_JSON_TIMESTAMPS, + JSON_TIMESTAMPS_INPUT as _SCHEMA_JSON_TIMESTAMPS_INPUT, + JSON_TIMESTAMPS_OUTPUT as _SCHEMA_JSON_TIMESTAMPS_OUTPUT, + JSON_UNIONS as _SCHEMA_JSON_UNIONS, + JSON_UNIONS_INPUT as _SCHEMA_JSON_UNIONS_INPUT, + JSON_UNIONS_OUTPUT as _SCHEMA_JSON_UNIONS_OUTPUT, + MALFORMED_ACCEPT_WITH_BODY as _SCHEMA_MALFORMED_ACCEPT_WITH_BODY, + MALFORMED_ACCEPT_WITH_BODY_INPUT as _SCHEMA_MALFORMED_ACCEPT_WITH_BODY_INPUT, + MALFORMED_ACCEPT_WITH_BODY_OUTPUT as _SCHEMA_MALFORMED_ACCEPT_WITH_BODY_OUTPUT, + MALFORMED_ACCEPT_WITH_GENERIC_STRING as _SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING, + MALFORMED_ACCEPT_WITH_GENERIC_STRING_INPUT as _SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_INPUT, + MALFORMED_ACCEPT_WITH_GENERIC_STRING_OUTPUT as _SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_OUTPUT, + MALFORMED_ACCEPT_WITH_PAYLOAD as _SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD, + MALFORMED_ACCEPT_WITH_PAYLOAD_INPUT as _SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_INPUT, + MALFORMED_ACCEPT_WITH_PAYLOAD_OUTPUT as _SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_OUTPUT, + MALFORMED_BLOB as _SCHEMA_MALFORMED_BLOB, + MALFORMED_BLOB_INPUT as _SCHEMA_MALFORMED_BLOB_INPUT, + MALFORMED_BLOB_OUTPUT as _SCHEMA_MALFORMED_BLOB_OUTPUT, + MALFORMED_BOOLEAN as _SCHEMA_MALFORMED_BOOLEAN, + MALFORMED_BOOLEAN_INPUT as _SCHEMA_MALFORMED_BOOLEAN_INPUT, + MALFORMED_BOOLEAN_OUTPUT as _SCHEMA_MALFORMED_BOOLEAN_OUTPUT, + MALFORMED_BYTE as _SCHEMA_MALFORMED_BYTE, + MALFORMED_BYTE_INPUT as _SCHEMA_MALFORMED_BYTE_INPUT, + MALFORMED_BYTE_OUTPUT as _SCHEMA_MALFORMED_BYTE_OUTPUT, + MALFORMED_CONTENT_TYPE_WITHOUT_BODY as _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY, + MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT, + MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_INPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_INPUT, + MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_OUTPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_OUTPUT, + MALFORMED_CONTENT_TYPE_WITHOUT_BODY_INPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_INPUT, + MALFORMED_CONTENT_TYPE_WITHOUT_BODY_OUTPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_OUTPUT, + MALFORMED_CONTENT_TYPE_WITH_BODY as _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY, + MALFORMED_CONTENT_TYPE_WITH_BODY_INPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_INPUT, + MALFORMED_CONTENT_TYPE_WITH_BODY_OUTPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_OUTPUT, + MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING as _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING, + MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_INPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_INPUT, + MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_OUTPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_OUTPUT, + MALFORMED_CONTENT_TYPE_WITH_PAYLOAD as _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD, + MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_INPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_INPUT, + MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_OUTPUT as _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_OUTPUT, + MALFORMED_DOUBLE as _SCHEMA_MALFORMED_DOUBLE, + MALFORMED_DOUBLE_INPUT as _SCHEMA_MALFORMED_DOUBLE_INPUT, + MALFORMED_DOUBLE_OUTPUT as _SCHEMA_MALFORMED_DOUBLE_OUTPUT, + MALFORMED_FLOAT as _SCHEMA_MALFORMED_FLOAT, + MALFORMED_FLOAT_INPUT as _SCHEMA_MALFORMED_FLOAT_INPUT, + MALFORMED_FLOAT_OUTPUT as _SCHEMA_MALFORMED_FLOAT_OUTPUT, + MALFORMED_INTEGER as _SCHEMA_MALFORMED_INTEGER, + MALFORMED_INTEGER_INPUT as _SCHEMA_MALFORMED_INTEGER_INPUT, + MALFORMED_INTEGER_OUTPUT as _SCHEMA_MALFORMED_INTEGER_OUTPUT, + MALFORMED_LIST as _SCHEMA_MALFORMED_LIST, + MALFORMED_LIST_INPUT as _SCHEMA_MALFORMED_LIST_INPUT, + MALFORMED_LIST_OUTPUT as _SCHEMA_MALFORMED_LIST_OUTPUT, + MALFORMED_LONG as _SCHEMA_MALFORMED_LONG, + MALFORMED_LONG_INPUT as _SCHEMA_MALFORMED_LONG_INPUT, + MALFORMED_LONG_OUTPUT as _SCHEMA_MALFORMED_LONG_OUTPUT, + MALFORMED_MAP as _SCHEMA_MALFORMED_MAP, + MALFORMED_MAP_INPUT as _SCHEMA_MALFORMED_MAP_INPUT, + MALFORMED_MAP_OUTPUT as _SCHEMA_MALFORMED_MAP_OUTPUT, + MALFORMED_REQUEST_BODY as _SCHEMA_MALFORMED_REQUEST_BODY, + MALFORMED_REQUEST_BODY_INPUT as _SCHEMA_MALFORMED_REQUEST_BODY_INPUT, + MALFORMED_REQUEST_BODY_OUTPUT as _SCHEMA_MALFORMED_REQUEST_BODY_OUTPUT, + MALFORMED_SHORT as _SCHEMA_MALFORMED_SHORT, + MALFORMED_SHORT_INPUT as _SCHEMA_MALFORMED_SHORT_INPUT, + MALFORMED_SHORT_OUTPUT as _SCHEMA_MALFORMED_SHORT_OUTPUT, + MALFORMED_STRING as _SCHEMA_MALFORMED_STRING, + MALFORMED_STRING_INPUT as _SCHEMA_MALFORMED_STRING_INPUT, + MALFORMED_STRING_OUTPUT as _SCHEMA_MALFORMED_STRING_OUTPUT, + MALFORMED_TIMESTAMP_BODY_DATE_TIME as _SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME, + MALFORMED_TIMESTAMP_BODY_DATE_TIME_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_INPUT, + MALFORMED_TIMESTAMP_BODY_DATE_TIME_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_OUTPUT, + MALFORMED_TIMESTAMP_BODY_DEFAULT as _SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT, + MALFORMED_TIMESTAMP_BODY_DEFAULT_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_INPUT, + MALFORMED_TIMESTAMP_BODY_DEFAULT_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_OUTPUT, + MALFORMED_TIMESTAMP_BODY_HTTP_DATE as _SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE, + MALFORMED_TIMESTAMP_BODY_HTTP_DATE_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_INPUT, + MALFORMED_TIMESTAMP_BODY_HTTP_DATE_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_OUTPUT, + MALFORMED_TIMESTAMP_HEADER_DATE_TIME as _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME, + MALFORMED_TIMESTAMP_HEADER_DATE_TIME_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_INPUT, + MALFORMED_TIMESTAMP_HEADER_DATE_TIME_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_OUTPUT, + MALFORMED_TIMESTAMP_HEADER_DEFAULT as _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT, + MALFORMED_TIMESTAMP_HEADER_DEFAULT_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_INPUT, + MALFORMED_TIMESTAMP_HEADER_DEFAULT_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_OUTPUT, + MALFORMED_TIMESTAMP_HEADER_EPOCH as _SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH, + MALFORMED_TIMESTAMP_HEADER_EPOCH_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_INPUT, + MALFORMED_TIMESTAMP_HEADER_EPOCH_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_OUTPUT, + MALFORMED_TIMESTAMP_PATH_DEFAULT as _SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT, + MALFORMED_TIMESTAMP_PATH_DEFAULT_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_INPUT, + MALFORMED_TIMESTAMP_PATH_DEFAULT_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_OUTPUT, + MALFORMED_TIMESTAMP_PATH_EPOCH as _SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH, + MALFORMED_TIMESTAMP_PATH_EPOCH_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_INPUT, + MALFORMED_TIMESTAMP_PATH_EPOCH_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_OUTPUT, + MALFORMED_TIMESTAMP_PATH_HTTP_DATE as _SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE, + MALFORMED_TIMESTAMP_PATH_HTTP_DATE_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_INPUT, + MALFORMED_TIMESTAMP_PATH_HTTP_DATE_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_OUTPUT, + MALFORMED_TIMESTAMP_QUERY_DEFAULT as _SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT, + MALFORMED_TIMESTAMP_QUERY_DEFAULT_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_INPUT, + MALFORMED_TIMESTAMP_QUERY_DEFAULT_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_OUTPUT, + MALFORMED_TIMESTAMP_QUERY_EPOCH as _SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH, + MALFORMED_TIMESTAMP_QUERY_EPOCH_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_INPUT, + MALFORMED_TIMESTAMP_QUERY_EPOCH_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_OUTPUT, + MALFORMED_TIMESTAMP_QUERY_HTTP_DATE as _SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE, + MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_INPUT as _SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_INPUT, + MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_OUTPUT as _SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_OUTPUT, + MALFORMED_UNION as _SCHEMA_MALFORMED_UNION, + MALFORMED_UNION_INPUT as _SCHEMA_MALFORMED_UNION_INPUT, + MALFORMED_UNION_OUTPUT as _SCHEMA_MALFORMED_UNION_OUTPUT, + MEDIA_TYPE_HEADER as _SCHEMA_MEDIA_TYPE_HEADER, + MEDIA_TYPE_HEADER_INPUT as _SCHEMA_MEDIA_TYPE_HEADER_INPUT, + MEDIA_TYPE_HEADER_OUTPUT as _SCHEMA_MEDIA_TYPE_HEADER_OUTPUT, + MY_UNION as _SCHEMA_MY_UNION, + NESTED_PAYLOAD as _SCHEMA_NESTED_PAYLOAD, + NESTED_UNION as _SCHEMA_NESTED_UNION, + NO_INPUT_AND_NO_OUTPUT as _SCHEMA_NO_INPUT_AND_NO_OUTPUT, + NO_INPUT_AND_NO_OUTPUT_INPUT as _SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, + NO_INPUT_AND_NO_OUTPUT_OUTPUT as _SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, + NO_INPUT_AND_OUTPUT as _SCHEMA_NO_INPUT_AND_OUTPUT, + NO_INPUT_AND_OUTPUT_INPUT as _SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, + NO_INPUT_AND_OUTPUT_OUTPUT as _SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, + NULL_AND_EMPTY_HEADERS_CLIENT as _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT, + NULL_AND_EMPTY_HEADERS_CLIENT_INPUT as _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT, + NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT as _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT, + NULL_AND_EMPTY_HEADERS_SERVER as _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER, + NULL_AND_EMPTY_HEADERS_SERVER_INPUT as _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT, + NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT as _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT, + OMITS_NULL_SERIALIZES_EMPTY_STRING as _SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING, + OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT as _SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT, + OMITS_NULL_SERIALIZES_EMPTY_STRING_OUTPUT as _SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_OUTPUT, + OMITS_SERIALIZING_EMPTY_LISTS as _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS, + OMITS_SERIALIZING_EMPTY_LISTS_INPUT as _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT, + OMITS_SERIALIZING_EMPTY_LISTS_OUTPUT as _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_OUTPUT, + OPERATION_WITH_DEFAULTS as _SCHEMA_OPERATION_WITH_DEFAULTS, + OPERATION_WITH_DEFAULTS_INPUT as _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT, + OPERATION_WITH_DEFAULTS_OUTPUT as _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT, + OPERATION_WITH_NESTED_STRUCTURE as _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE, + OPERATION_WITH_NESTED_STRUCTURE_INPUT as _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT, + OPERATION_WITH_NESTED_STRUCTURE_OUTPUT as _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT, + OUTPUT_STREAM as _SCHEMA_OUTPUT_STREAM, + OUTPUT_STREAM_INPUT as _SCHEMA_OUTPUT_STREAM_INPUT, + OUTPUT_STREAM_OUTPUT as _SCHEMA_OUTPUT_STREAM_OUTPUT, + OUTPUT_STREAM_WITH_INITIAL_RESPONSE as _SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE, + OUTPUT_STREAM_WITH_INITIAL_RESPONSE_INPUT as _SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_INPUT, + OUTPUT_STREAM_WITH_INITIAL_RESPONSE_OUTPUT as _SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_OUTPUT, + PAYLOAD_CONFIG as _SCHEMA_PAYLOAD_CONFIG, + PAYLOAD_STRUCTURE as _SCHEMA_PAYLOAD_STRUCTURE, + PAYLOAD_UNION as _SCHEMA_PAYLOAD_UNION, + PLAYER_ACTION as _SCHEMA_PLAYER_ACTION, + POST_PLAYER_ACTION as _SCHEMA_POST_PLAYER_ACTION, + POST_PLAYER_ACTION_INPUT as _SCHEMA_POST_PLAYER_ACTION_INPUT, + POST_PLAYER_ACTION_OUTPUT as _SCHEMA_POST_PLAYER_ACTION_OUTPUT, + POST_UNION_WITH_JSON_NAME as _SCHEMA_POST_UNION_WITH_JSON_NAME, + POST_UNION_WITH_JSON_NAME_INPUT as _SCHEMA_POST_UNION_WITH_JSON_NAME_INPUT, + POST_UNION_WITH_JSON_NAME_OUTPUT as _SCHEMA_POST_UNION_WITH_JSON_NAME_OUTPUT, + PUT_WITH_CONTENT_ENCODING as _SCHEMA_PUT_WITH_CONTENT_ENCODING, + PUT_WITH_CONTENT_ENCODING_INPUT as _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, + PUT_WITH_CONTENT_ENCODING_OUTPUT as _SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, + QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL as _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL, + QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT as _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT, + QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT as _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT, + QUERY_PARAMS_AS_STRING_LIST_MAP as _SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP, + QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT as _SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT, + QUERY_PARAMS_AS_STRING_LIST_MAP_OUTPUT as _SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_OUTPUT, + QUERY_PRECEDENCE as _SCHEMA_QUERY_PRECEDENCE, + QUERY_PRECEDENCE_INPUT as _SCHEMA_QUERY_PRECEDENCE_INPUT, + QUERY_PRECEDENCE_OUTPUT as _SCHEMA_QUERY_PRECEDENCE_OUTPUT, + RECURSIVE_SHAPES as _SCHEMA_RECURSIVE_SHAPES, + RECURSIVE_SHAPES_INPUT as _SCHEMA_RECURSIVE_SHAPES_INPUT, + RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1 as _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1, + RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED2 as _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED2, + RECURSIVE_SHAPES_OUTPUT as _SCHEMA_RECURSIVE_SHAPES_OUTPUT, + RENAMED_GREETING as _SCHEMA_RENAMED_GREETING, + RESPONSE_CODE_HTTP_FALLBACK as _SCHEMA_RESPONSE_CODE_HTTP_FALLBACK, + RESPONSE_CODE_HTTP_FALLBACK_INPUT as _SCHEMA_RESPONSE_CODE_HTTP_FALLBACK_INPUT, + RESPONSE_CODE_HTTP_FALLBACK_OUTPUT as _SCHEMA_RESPONSE_CODE_HTTP_FALLBACK_OUTPUT, + RESPONSE_CODE_REQUIRED as _SCHEMA_RESPONSE_CODE_REQUIRED, + RESPONSE_CODE_REQUIRED_INPUT as _SCHEMA_RESPONSE_CODE_REQUIRED_INPUT, + RESPONSE_CODE_REQUIRED_OUTPUT as _SCHEMA_RESPONSE_CODE_REQUIRED_OUTPUT, + SERVICE_UNAVAILABLE_ERROR as _SCHEMA_SERVICE_UNAVAILABLE_ERROR, + SIMPLE_SCALAR_PROPERTIES as _SCHEMA_SIMPLE_SCALAR_PROPERTIES, + SIMPLE_SCALAR_PROPERTIES_INPUT as _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, + SIMPLE_SCALAR_PROPERTIES_OUTPUT as _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, + SIMPLE_UNION as _SCHEMA_SIMPLE_UNION, + SINGLETON_EVENT as _SCHEMA_SINGLETON_EVENT, + SINGLETON_EVENT_STREAM as _SCHEMA_SINGLETON_EVENT_STREAM, + SPARSE_JSON_LISTS as _SCHEMA_SPARSE_JSON_LISTS, + SPARSE_JSON_LISTS_INPUT as _SCHEMA_SPARSE_JSON_LISTS_INPUT, + SPARSE_JSON_LISTS_OUTPUT as _SCHEMA_SPARSE_JSON_LISTS_OUTPUT, + SPARSE_JSON_MAPS as _SCHEMA_SPARSE_JSON_MAPS, + SPARSE_JSON_MAPS_INPUT as _SCHEMA_SPARSE_JSON_MAPS_INPUT, + SPARSE_JSON_MAPS_OUTPUT as _SCHEMA_SPARSE_JSON_MAPS_OUTPUT, + STREAMING_TRAITS as _SCHEMA_STREAMING_TRAITS, + STREAMING_TRAITS_INPUT as _SCHEMA_STREAMING_TRAITS_INPUT, + STREAMING_TRAITS_OUTPUT as _SCHEMA_STREAMING_TRAITS_OUTPUT, + STREAMING_TRAITS_REQUIRE_LENGTH as _SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH, + STREAMING_TRAITS_REQUIRE_LENGTH_INPUT as _SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_INPUT, + STREAMING_TRAITS_REQUIRE_LENGTH_OUTPUT as _SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_OUTPUT, + STREAMING_TRAITS_WITH_MEDIA_TYPE as _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE, + STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT as _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT, + STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT as _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT, + STRING_PAYLOAD_EVENT as _SCHEMA_STRING_PAYLOAD_EVENT, + STRUCTURE_LIST_MEMBER as _SCHEMA_STRUCTURE_LIST_MEMBER, + STRUCTURE_PAYLOAD_EVENT as _SCHEMA_STRUCTURE_PAYLOAD_EVENT, + TEST_BODY_STRUCTURE as _SCHEMA_TEST_BODY_STRUCTURE, + TEST_BODY_STRUCTURE_INPUT as _SCHEMA_TEST_BODY_STRUCTURE_INPUT, + TEST_BODY_STRUCTURE_OUTPUT as _SCHEMA_TEST_BODY_STRUCTURE_OUTPUT, + TEST_CONFIG as _SCHEMA_TEST_CONFIG, + TEST_GET_NO_INPUT_NO_PAYLOAD as _SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD, + TEST_GET_NO_INPUT_NO_PAYLOAD_INPUT as _SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_INPUT, + TEST_GET_NO_INPUT_NO_PAYLOAD_OUTPUT as _SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_OUTPUT, + TEST_GET_NO_PAYLOAD as _SCHEMA_TEST_GET_NO_PAYLOAD, + TEST_GET_NO_PAYLOAD_INPUT as _SCHEMA_TEST_GET_NO_PAYLOAD_INPUT, + TEST_GET_NO_PAYLOAD_OUTPUT as _SCHEMA_TEST_GET_NO_PAYLOAD_OUTPUT, + TEST_PAYLOAD_BLOB as _SCHEMA_TEST_PAYLOAD_BLOB, + TEST_PAYLOAD_BLOB_INPUT as _SCHEMA_TEST_PAYLOAD_BLOB_INPUT, + TEST_PAYLOAD_BLOB_OUTPUT as _SCHEMA_TEST_PAYLOAD_BLOB_OUTPUT, + TEST_PAYLOAD_STRUCTURE as _SCHEMA_TEST_PAYLOAD_STRUCTURE, + TEST_PAYLOAD_STRUCTURE_INPUT as _SCHEMA_TEST_PAYLOAD_STRUCTURE_INPUT, + TEST_PAYLOAD_STRUCTURE_OUTPUT as _SCHEMA_TEST_PAYLOAD_STRUCTURE_OUTPUT, + TEST_POST_NO_INPUT_NO_PAYLOAD as _SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD, + TEST_POST_NO_INPUT_NO_PAYLOAD_INPUT as _SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_INPUT, + TEST_POST_NO_INPUT_NO_PAYLOAD_OUTPUT as _SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_OUTPUT, + TEST_POST_NO_PAYLOAD as _SCHEMA_TEST_POST_NO_PAYLOAD, + TEST_POST_NO_PAYLOAD_INPUT as _SCHEMA_TEST_POST_NO_PAYLOAD_INPUT, + TEST_POST_NO_PAYLOAD_OUTPUT as _SCHEMA_TEST_POST_NO_PAYLOAD_OUTPUT, + TIMESTAMP_FORMAT_HEADERS as _SCHEMA_TIMESTAMP_FORMAT_HEADERS, + TIMESTAMP_FORMAT_HEADERS_INPUT as _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT, + TIMESTAMP_FORMAT_HEADERS_OUTPUT as _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT, + TOP_LEVEL as _SCHEMA_TOP_LEVEL, + UNION_PAYLOAD as _SCHEMA_UNION_PAYLOAD, + UNION_PAYLOAD_EVENT as _SCHEMA_UNION_PAYLOAD_EVENT, + UNION_WITH_JSON_NAME as _SCHEMA_UNION_WITH_JSON_NAME, + UNIT_INPUT_AND_OUTPUT as _SCHEMA_UNIT_INPUT_AND_OUTPUT, + UNIT_INPUT_AND_OUTPUT_INPUT as _SCHEMA_UNIT_INPUT_AND_OUTPUT_INPUT, + UNIT_INPUT_AND_OUTPUT_OUTPUT as _SCHEMA_UNIT_INPUT_AND_OUTPUT_OUTPUT, +) + + +logger = logging.getLogger(__name__) + + +class ServiceError(ModeledError): + """ + Base error for all errors in the service. + + Some exceptions do not extend from this class, including + synthetic, implicit, and shared exception types. + """ + + +def _serialize_boolean_list( + serializer: ShapeSerializer, schema: Schema, value: list[bool] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_boolean(member_schema, e) + + +def _deserialize_boolean_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[bool]: + result: list[bool] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_boolean(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_double_list( + serializer: ShapeSerializer, schema: Schema, value: list[float] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_double(member_schema, e) + + +def _deserialize_double_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[float]: + result: list[float] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_double(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +class FooEnum(UnknownEnumMixin, StrEnum): + FOO = "Foo" + BAZ = "Baz" + BAR = "Bar" + ONE = "1" + ZERO = "0" + + +def _serialize_foo_enum_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_foo_enum_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(FooEnum(d.read_string(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +class IntegerEnum(UnknownEnumMixin, IntEnum): + A = 1 + B = 2 + C = 3 + + +def _serialize_integer_enum_list( + serializer: ShapeSerializer, schema: Schema, value: list[int] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_integer(member_schema, e) + + +def _deserialize_integer_enum_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int]: + result: list[int] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(IntegerEnum(d.read_integer(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_integer_list( + serializer: ShapeSerializer, schema: Schema, value: list[int] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_integer(member_schema, e) + + +def _deserialize_integer_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int]: + result: list[int] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_integer(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_integer_set( + serializer: ShapeSerializer, schema: Schema, value: list[int] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_integer(member_schema, e) + + +def _deserialize_integer_set( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int]: + result: list[int] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_integer(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_string_list_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, list[str]] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: _serialize_string_list(vs, value_schema, v)) + + +def _deserialize_string_list_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, list[str]]: + result: dict[str, list[str]] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = _deserialize_string_list(d, value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_string_set( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_string_set( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_timestamp_list( + serializer: ShapeSerializer, schema: Schema, value: list[datetime] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_timestamp(member_schema, e) + + +def _deserialize_timestamp_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[datetime]: + result: list[datetime] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_timestamp(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class AllQueryStringTypesInput: + """Dataclass for AllQueryStringTypesInput structure.""" + + query_string: str | None = None + + query_string_list: list[str] | None = None + + query_string_set: list[str] | None = None + + query_byte: int | None = None + + query_short: int | None = None + + query_integer: int | None = None + + query_integer_list: list[int] | None = None + + query_integer_set: list[int] | None = None + + query_long: int | None = None + + query_float: float | None = None + + query_double: float | None = None + + query_double_list: list[float] | None = None + + query_boolean: bool | None = None + + query_boolean_list: list[bool] | None = None + + query_timestamp: datetime | None = None + + query_timestamp_list: list[datetime] | None = None + + query_enum: str | None = None + + query_enum_list: list[str] | None = None + + query_integer_enum: int | None = None + + query_integer_enum_list: list[int] | None = None + + query_params_map_of_string_list: dict[str, list[str]] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ALL_QUERY_STRING_TYPES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.query_string is not None: + serializer.write_string( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryString"], + self.query_string, + ) + + if self.query_string_list is not None: + _serialize_string_list( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryStringList"], + self.query_string_list, + ) + + if self.query_string_set is not None: + _serialize_string_set( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryStringSet"], + self.query_string_set, + ) + + if self.query_byte is not None: + serializer.write_byte( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryByte"], + self.query_byte, + ) + + if self.query_short is not None: + serializer.write_short( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryShort"], + self.query_short, + ) + + if self.query_integer is not None: + serializer.write_integer( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryInteger"], + self.query_integer, + ) + + if self.query_integer_list is not None: + _serialize_integer_list( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryIntegerList"], + self.query_integer_list, + ) + + if self.query_integer_set is not None: + _serialize_integer_set( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryIntegerSet"], + self.query_integer_set, + ) + + if self.query_long is not None: + serializer.write_long( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryLong"], + self.query_long, + ) + + if self.query_float is not None: + serializer.write_float( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryFloat"], + self.query_float, + ) + + if self.query_double is not None: + serializer.write_double( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryDouble"], + self.query_double, + ) + + if self.query_double_list is not None: + _serialize_double_list( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryDoubleList"], + self.query_double_list, + ) + + if self.query_boolean is not None: + serializer.write_boolean( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryBoolean"], + self.query_boolean, + ) + + if self.query_boolean_list is not None: + _serialize_boolean_list( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryBooleanList"], + self.query_boolean_list, + ) + + if self.query_timestamp is not None: + serializer.write_timestamp( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryTimestamp"], + self.query_timestamp, + ) + + if self.query_timestamp_list is not None: + _serialize_timestamp_list( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryTimestampList"], + self.query_timestamp_list, + ) + + if self.query_enum is not None: + serializer.write_string( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryEnum"], + self.query_enum, + ) + + if self.query_enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryEnumList"], + self.query_enum_list, + ) + + if self.query_integer_enum is not None: + serializer.write_integer( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryIntegerEnum"], + self.query_integer_enum, + ) + + if self.query_integer_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryIntegerEnumList"], + self.query_integer_enum_list, + ) + + if self.query_params_map_of_string_list is not None: + _serialize_string_list_map( + serializer, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members[ + "queryParamsMapOfStringList" + ], + self.query_params_map_of_string_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["query_string"] = de.read_string( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryString"] + ) + + case 1: + kwargs["query_string_list"] = _deserialize_string_list( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryStringList"], + ) + + case 2: + kwargs["query_string_set"] = _deserialize_string_set( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryStringSet"], + ) + + case 3: + kwargs["query_byte"] = de.read_byte( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryByte"] + ) + + case 4: + kwargs["query_short"] = de.read_short( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryShort"] + ) + + case 5: + kwargs["query_integer"] = de.read_integer( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryInteger"] + ) + + case 6: + kwargs["query_integer_list"] = _deserialize_integer_list( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members[ + "queryIntegerList" + ], + ) + + case 7: + kwargs["query_integer_set"] = _deserialize_integer_set( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryIntegerSet"], + ) + + case 8: + kwargs["query_long"] = de.read_long( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryLong"] + ) + + case 9: + kwargs["query_float"] = de.read_float( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryFloat"] + ) + + case 10: + kwargs["query_double"] = de.read_double( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryDouble"] + ) + + case 11: + kwargs["query_double_list"] = _deserialize_double_list( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryDoubleList"], + ) + + case 12: + kwargs["query_boolean"] = de.read_boolean( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryBoolean"] + ) + + case 13: + kwargs["query_boolean_list"] = _deserialize_boolean_list( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members[ + "queryBooleanList" + ], + ) + + case 14: + kwargs["query_timestamp"] = de.read_timestamp( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryTimestamp"] + ) + + case 15: + kwargs["query_timestamp_list"] = _deserialize_timestamp_list( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members[ + "queryTimestampList" + ], + ) + + case 16: + kwargs["query_enum"] = FooEnum( + de.read_string( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryEnum"] + ) + ) + + case 17: + kwargs["query_enum_list"] = _deserialize_foo_enum_list( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members["queryEnumList"], + ) + + case 18: + kwargs["query_integer_enum"] = IntegerEnum( + de.read_integer( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members[ + "queryIntegerEnum" + ] + ) + ) + + case 19: + kwargs["query_integer_enum_list"] = _deserialize_integer_enum_list( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members[ + "queryIntegerEnumList" + ], + ) + + case 20: + kwargs["query_params_map_of_string_list"] = ( + _deserialize_string_list_map( + de, + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT.members[ + "queryParamsMapOfStringList" + ], + ) + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ALL_QUERY_STRING_TYPES_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class AllQueryStringTypesOutput: + """Dataclass for AllQueryStringTypesOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ALL_QUERY_STRING_TYPES_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ALL_QUERY_STRING_TYPES_OUTPUT, consumer=_consumer + ) + return kwargs + + +ALL_QUERY_STRING_TYPES = APIOperation( + input=AllQueryStringTypesInput, + output=AllQueryStringTypesOutput, + schema=_SCHEMA_ALL_QUERY_STRING_TYPES, + input_schema=_SCHEMA_ALL_QUERY_STRING_TYPES_INPUT, + output_schema=_SCHEMA_ALL_QUERY_STRING_TYPES_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class BlobPayloadEvent: + """Dataclass for BlobPayloadEvent structure.""" + + payload: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_BLOB_PAYLOAD_EVENT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_blob( + _SCHEMA_BLOB_PAYLOAD_EVENT.members["payload"], self.payload + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = de.read_blob( + _SCHEMA_BLOB_PAYLOAD_EVENT.members["payload"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_BLOB_PAYLOAD_EVENT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ClientOptionalDefaults: + """Dataclass for ClientOptionalDefaults structure.""" + + member: int = 0 + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CLIENT_OPTIONAL_DEFAULTS, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.member is not None: + serializer.write_integer( + _SCHEMA_CLIENT_OPTIONAL_DEFAULTS.members["member"], self.member + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["member"] = de.read_integer( + _SCHEMA_CLIENT_OPTIONAL_DEFAULTS.members["member"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_CLIENT_OPTIONAL_DEFAULTS, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ComplexNestedErrorData: + """Dataclass for ComplexNestedErrorData structure.""" + + foo: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_COMPLEX_NESTED_ERROR_DATA, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_COMPLEX_NESTED_ERROR_DATA.members["Foo"], self.foo + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_COMPLEX_NESTED_ERROR_DATA.members["Foo"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_COMPLEX_NESTED_ERROR_DATA, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ComplexError(ServiceError): + """This error is thrown when a request is invalid.""" + + fault: Literal["client", "server"] | None = "client" + + header: str | None = None + + top_level: str | None = None + + nested: ComplexNestedErrorData | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_COMPLEX_ERROR, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.header is not None: + serializer.write_string( + _SCHEMA_COMPLEX_ERROR.members["Header"], self.header + ) + + if self.top_level is not None: + serializer.write_string( + _SCHEMA_COMPLEX_ERROR.members["TopLevel"], self.top_level + ) + + if self.nested is not None: + serializer.write_struct( + _SCHEMA_COMPLEX_ERROR.members["Nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["header"] = de.read_string( + _SCHEMA_COMPLEX_ERROR.members["Header"] + ) + + case 1: + kwargs["top_level"] = de.read_string( + _SCHEMA_COMPLEX_ERROR.members["TopLevel"] + ) + + case 2: + kwargs["nested"] = ComplexNestedErrorData.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_COMPLEX_ERROR, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class ConstantAndVariableQueryStringInput: + """Dataclass for ConstantAndVariableQueryStringInput structure.""" + + baz: str | None = None + + maybe_set: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.baz is not None: + serializer.write_string( + _SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT.members["baz"], + self.baz, + ) + + if self.maybe_set is not None: + serializer.write_string( + _SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT.members["maybeSet"], + self.maybe_set, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["baz"] = de.read_string( + _SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT.members["baz"] + ) + + case 1: + kwargs["maybe_set"] = de.read_string( + _SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT.members[ + "maybeSet" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class ConstantAndVariableQueryStringOutput: + """Dataclass for ConstantAndVariableQueryStringOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_OUTPUT, consumer=_consumer + ) + return kwargs + + +CONSTANT_AND_VARIABLE_QUERY_STRING = APIOperation( + input=ConstantAndVariableQueryStringInput, + output=ConstantAndVariableQueryStringOutput, + schema=_SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING, + input_schema=_SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_INPUT, + output_schema=_SCHEMA_CONSTANT_AND_VARIABLE_QUERY_STRING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class ConstantQueryStringInput: + """Dataclass for ConstantQueryStringInput structure.""" + + hello: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONSTANT_QUERY_STRING_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.hello is not None: + serializer.write_string( + _SCHEMA_CONSTANT_QUERY_STRING_INPUT.members["hello"], self.hello + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["hello"] = de.read_string( + _SCHEMA_CONSTANT_QUERY_STRING_INPUT.members["hello"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONSTANT_QUERY_STRING_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class ConstantQueryStringOutput: + """Dataclass for ConstantQueryStringOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONSTANT_QUERY_STRING_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONSTANT_QUERY_STRING_OUTPUT, consumer=_consumer + ) + return kwargs + + +CONSTANT_QUERY_STRING = APIOperation( + input=ConstantQueryStringInput, + output=ConstantQueryStringOutput, + schema=_SCHEMA_CONSTANT_QUERY_STRING, + input_schema=_SCHEMA_CONSTANT_QUERY_STRING_INPUT, + output_schema=_SCHEMA_CONSTANT_QUERY_STRING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class ContentTypeParametersInput: + """Dataclass for ContentTypeParametersInput structure.""" + + value: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.value is not None: + serializer.write_integer( + _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT.members["value"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = de.read_integer( + _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT.members["value"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class ContentTypeParametersOutput: + """Dataclass for ContentTypeParametersOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, consumer=_consumer + ) + return kwargs + + +CONTENT_TYPE_PARAMETERS = APIOperation( + input=ContentTypeParametersInput, + output=ContentTypeParametersOutput, + schema=_SCHEMA_CONTENT_TYPE_PARAMETERS, + input_schema=_SCHEMA_CONTENT_TYPE_PARAMETERS_INPUT, + output_schema=_SCHEMA_CONTENT_TYPE_PARAMETERS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class DatetimeOffsetsInput: + """Dataclass for DatetimeOffsetsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DATETIME_OFFSETS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DATETIME_OFFSETS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class DatetimeOffsetsOutput: + """Dataclass for DatetimeOffsetsOutput structure.""" + + datetime_: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DATETIME_OFFSETS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.datetime_ is not None: + serializer.write_timestamp( + _SCHEMA_DATETIME_OFFSETS_OUTPUT.members["datetime"], self.datetime_ + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["datetime_"] = de.read_timestamp( + _SCHEMA_DATETIME_OFFSETS_OUTPUT.members["datetime"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DATETIME_OFFSETS_OUTPUT, consumer=_consumer) + return kwargs + + +DATETIME_OFFSETS = APIOperation( + input=DatetimeOffsetsInput, + output=DatetimeOffsetsOutput, + schema=_SCHEMA_DATETIME_OFFSETS, + input_schema=_SCHEMA_DATETIME_OFFSETS_INPUT, + output_schema=_SCHEMA_DATETIME_OFFSETS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +class TestEnum(UnknownEnumMixin, StrEnum): + FOO = "FOO" + BAR = "BAR" + BAZ = "BAZ" + + +class TestIntEnum(UnknownEnumMixin, IntEnum): + ONE = 1 + TWO = 2 + + +def _serialize_test_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_test_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_test_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_test_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class Defaults: + """Dataclass for Defaults structure.""" + + default_string: str = "hi" + + default_boolean: bool = True + + default_list: list[str] = field(default_factory=list[str]) + + default_document_map: Document = field(default_factory=lambda: Document(dict())) + + default_document_string: Document = field(default_factory=lambda: Document("hi")) + + default_document_boolean: Document = field(default_factory=lambda: Document(True)) + + default_document_list: Document = field(default_factory=lambda: Document(list())) + + default_null_document: Document = field(default_factory=lambda: Document(None)) + + default_timestamp: datetime = datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc) + + default_blob: bytes = b64decode("YWJj") + + default_byte: int = 1 + + default_short: int = 1 + + default_integer: int = 10 + + default_long: int = 100 + + default_float: float = 1.0 + + default_double: float = 1.0 + + default_map: dict[str, str] = field(default_factory=dict[str, str]) + + default_enum: str = TestEnum("FOO") + + default_int_enum: int = TestIntEnum(1) + + empty_string: str = "" + + false_boolean: bool = False + + empty_blob: bytes = b64decode("") + + zero_byte: int = 0 + + zero_short: int = 0 + + zero_integer: int = 0 + + zero_long: int = 0 + + zero_float: float = 0.0 + + zero_double: float = 0.0 + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DEFAULTS, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string( + _SCHEMA_DEFAULTS.members["defaultString"], self.default_string + ) + serializer.write_boolean( + _SCHEMA_DEFAULTS.members["defaultBoolean"], self.default_boolean + ) + _serialize_test_string_list( + serializer, _SCHEMA_DEFAULTS.members["defaultList"], self.default_list + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultDocumentMap"], self.default_document_map + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultDocumentString"], + self.default_document_string, + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultDocumentBoolean"], + self.default_document_boolean, + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultDocumentList"], self.default_document_list + ) + serializer.write_document( + _SCHEMA_DEFAULTS.members["defaultNullDocument"], self.default_null_document + ) + serializer.write_timestamp( + _SCHEMA_DEFAULTS.members["defaultTimestamp"], self.default_timestamp + ) + serializer.write_blob( + _SCHEMA_DEFAULTS.members["defaultBlob"], self.default_blob + ) + serializer.write_byte( + _SCHEMA_DEFAULTS.members["defaultByte"], self.default_byte + ) + serializer.write_short( + _SCHEMA_DEFAULTS.members["defaultShort"], self.default_short + ) + serializer.write_integer( + _SCHEMA_DEFAULTS.members["defaultInteger"], self.default_integer + ) + serializer.write_long( + _SCHEMA_DEFAULTS.members["defaultLong"], self.default_long + ) + serializer.write_float( + _SCHEMA_DEFAULTS.members["defaultFloat"], self.default_float + ) + serializer.write_double( + _SCHEMA_DEFAULTS.members["defaultDouble"], self.default_double + ) + _serialize_test_string_map( + serializer, _SCHEMA_DEFAULTS.members["defaultMap"], self.default_map + ) + serializer.write_string( + _SCHEMA_DEFAULTS.members["defaultEnum"], self.default_enum + ) + serializer.write_integer( + _SCHEMA_DEFAULTS.members["defaultIntEnum"], self.default_int_enum + ) + serializer.write_string( + _SCHEMA_DEFAULTS.members["emptyString"], self.empty_string + ) + serializer.write_boolean( + _SCHEMA_DEFAULTS.members["falseBoolean"], self.false_boolean + ) + serializer.write_blob(_SCHEMA_DEFAULTS.members["emptyBlob"], self.empty_blob) + serializer.write_byte(_SCHEMA_DEFAULTS.members["zeroByte"], self.zero_byte) + serializer.write_short(_SCHEMA_DEFAULTS.members["zeroShort"], self.zero_short) + serializer.write_integer( + _SCHEMA_DEFAULTS.members["zeroInteger"], self.zero_integer + ) + serializer.write_long(_SCHEMA_DEFAULTS.members["zeroLong"], self.zero_long) + serializer.write_float(_SCHEMA_DEFAULTS.members["zeroFloat"], self.zero_float) + serializer.write_double( + _SCHEMA_DEFAULTS.members["zeroDouble"], self.zero_double + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["default_string"] = de.read_string( + _SCHEMA_DEFAULTS.members["defaultString"] + ) + + case 1: + kwargs["default_boolean"] = de.read_boolean( + _SCHEMA_DEFAULTS.members["defaultBoolean"] + ) + + case 2: + kwargs["default_list"] = _deserialize_test_string_list( + de, _SCHEMA_DEFAULTS.members["defaultList"] + ) + + case 3: + kwargs["default_document_map"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultDocumentMap"] + ) + + case 4: + kwargs["default_document_string"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultDocumentString"] + ) + + case 5: + kwargs["default_document_boolean"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultDocumentBoolean"] + ) + + case 6: + kwargs["default_document_list"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultDocumentList"] + ) + + case 7: + kwargs["default_null_document"] = de.read_document( + _SCHEMA_DEFAULTS.members["defaultNullDocument"] + ) + + case 8: + kwargs["default_timestamp"] = de.read_timestamp( + _SCHEMA_DEFAULTS.members["defaultTimestamp"] + ) + + case 9: + kwargs["default_blob"] = de.read_blob( + _SCHEMA_DEFAULTS.members["defaultBlob"] + ) + + case 10: + kwargs["default_byte"] = de.read_byte( + _SCHEMA_DEFAULTS.members["defaultByte"] + ) + + case 11: + kwargs["default_short"] = de.read_short( + _SCHEMA_DEFAULTS.members["defaultShort"] + ) + + case 12: + kwargs["default_integer"] = de.read_integer( + _SCHEMA_DEFAULTS.members["defaultInteger"] + ) + + case 13: + kwargs["default_long"] = de.read_long( + _SCHEMA_DEFAULTS.members["defaultLong"] + ) + + case 14: + kwargs["default_float"] = de.read_float( + _SCHEMA_DEFAULTS.members["defaultFloat"] + ) + + case 15: + kwargs["default_double"] = de.read_double( + _SCHEMA_DEFAULTS.members["defaultDouble"] + ) + + case 16: + kwargs["default_map"] = _deserialize_test_string_map( + de, _SCHEMA_DEFAULTS.members["defaultMap"] + ) + + case 17: + kwargs["default_enum"] = TestEnum( + de.read_string(_SCHEMA_DEFAULTS.members["defaultEnum"]) + ) + + case 18: + kwargs["default_int_enum"] = TestIntEnum( + de.read_integer(_SCHEMA_DEFAULTS.members["defaultIntEnum"]) + ) + + case 19: + kwargs["empty_string"] = de.read_string( + _SCHEMA_DEFAULTS.members["emptyString"] + ) + + case 20: + kwargs["false_boolean"] = de.read_boolean( + _SCHEMA_DEFAULTS.members["falseBoolean"] + ) + + case 21: + kwargs["empty_blob"] = de.read_blob( + _SCHEMA_DEFAULTS.members["emptyBlob"] + ) + + case 22: + kwargs["zero_byte"] = de.read_byte( + _SCHEMA_DEFAULTS.members["zeroByte"] + ) + + case 23: + kwargs["zero_short"] = de.read_short( + _SCHEMA_DEFAULTS.members["zeroShort"] + ) + + case 24: + kwargs["zero_integer"] = de.read_integer( + _SCHEMA_DEFAULTS.members["zeroInteger"] + ) + + case 25: + kwargs["zero_long"] = de.read_long( + _SCHEMA_DEFAULTS.members["zeroLong"] + ) + + case 26: + kwargs["zero_float"] = de.read_float( + _SCHEMA_DEFAULTS.members["zeroFloat"] + ) + + case 27: + kwargs["zero_double"] = de.read_double( + _SCHEMA_DEFAULTS.members["zeroDouble"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DEFAULTS, consumer=_consumer) + return kwargs + + +def _serialize_dense_boolean_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, bool] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_boolean(value_schema, v)) + + +def _deserialize_dense_boolean_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, bool]: + result: dict[str, bool] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_boolean(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_dense_number_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, int] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_integer(value_schema, v)) + + +def _deserialize_dense_number_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, int]: + result: dict[str, int] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_integer(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_dense_set_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, list[str]] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: _serialize_string_set(vs, value_schema, v)) + + +def _deserialize_dense_set_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, list[str]]: + result: dict[str, list[str]] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = _deserialize_string_set(d, value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_dense_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_dense_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class GreetingStruct: + """Dataclass for GreetingStruct structure.""" + + hi: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_STRUCT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.hi is not None: + serializer.write_string(_SCHEMA_GREETING_STRUCT.members["hi"], self.hi) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["hi"] = de.read_string(_SCHEMA_GREETING_STRUCT.members["hi"]) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_GREETING_STRUCT, consumer=_consumer) + return kwargs + + +def _serialize_dense_struct_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, GreetingStruct] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_struct(value_schema, v)) + + +def _deserialize_dense_struct_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, GreetingStruct]: + result: dict[str, GreetingStruct] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = GreetingStruct.deserialize(d) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class Farewell: + """Dataclass for Farewell structure.""" + + phrase: str = "bye" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FAREWELL, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_FAREWELL.members["phrase"], self.phrase) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["phrase"] = de.read_string( + _SCHEMA_FAREWELL.members["phrase"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FAREWELL, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class Dialog: + """Dataclass for Dialog structure.""" + + language: str | None = None + + greeting: str = "hi" + + farewell: Farewell | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DIALOG, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.language is not None: + serializer.write_string(_SCHEMA_DIALOG.members["language"], self.language) + + serializer.write_string(_SCHEMA_DIALOG.members["greeting"], self.greeting) + if self.farewell is not None: + serializer.write_struct(_SCHEMA_DIALOG.members["farewell"], self.farewell) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["language"] = de.read_string( + _SCHEMA_DIALOG.members["language"] + ) + + case 1: + kwargs["greeting"] = de.read_string( + _SCHEMA_DIALOG.members["greeting"] + ) + + case 2: + kwargs["farewell"] = Farewell.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DIALOG, consumer=_consumer) + return kwargs + + @classmethod + def _smithy_default(cls) -> Self: + return cls() + + +def _serialize_dialog_list( + serializer: ShapeSerializer, schema: Schema, value: list[Dialog] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_struct(member_schema, e) + + +def _deserialize_dialog_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[Dialog]: + result: list[Dialog] = [] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(Dialog.deserialize(d)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_dialog_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, Dialog] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_struct(value_schema, v)) + + +def _deserialize_dialog_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, Dialog]: + result: dict[str, Dialog] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = Dialog.deserialize(d) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class DocumentTypeInput: + """Dataclass for DocumentTypeInput structure.""" + + string_value: str | None = None + + document_value: Document | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DOCUMENT_TYPE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string_value is not None: + serializer.write_string( + _SCHEMA_DOCUMENT_TYPE_INPUT.members["stringValue"], self.string_value + ) + + if self.document_value is not None: + serializer.write_document( + _SCHEMA_DOCUMENT_TYPE_INPUT.members["documentValue"], + self.document_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string_value"] = de.read_string( + _SCHEMA_DOCUMENT_TYPE_INPUT.members["stringValue"] + ) + + case 1: + kwargs["document_value"] = de.read_document( + _SCHEMA_DOCUMENT_TYPE_INPUT.members["documentValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DOCUMENT_TYPE_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class DocumentTypeOutput: + """Dataclass for DocumentTypeOutput structure.""" + + string_value: str | None = None + + document_value: Document | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DOCUMENT_TYPE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string_value is not None: + serializer.write_string( + _SCHEMA_DOCUMENT_TYPE_OUTPUT.members["stringValue"], self.string_value + ) + + if self.document_value is not None: + serializer.write_document( + _SCHEMA_DOCUMENT_TYPE_OUTPUT.members["documentValue"], + self.document_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string_value"] = de.read_string( + _SCHEMA_DOCUMENT_TYPE_OUTPUT.members["stringValue"] + ) + + case 1: + kwargs["document_value"] = de.read_document( + _SCHEMA_DOCUMENT_TYPE_OUTPUT.members["documentValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DOCUMENT_TYPE_OUTPUT, consumer=_consumer) + return kwargs + + +DOCUMENT_TYPE = APIOperation( + input=DocumentTypeInput, + output=DocumentTypeOutput, + schema=_SCHEMA_DOCUMENT_TYPE, + input_schema=_SCHEMA_DOCUMENT_TYPE_INPUT, + output_schema=_SCHEMA_DOCUMENT_TYPE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_document_valued_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, Document] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_document(value_schema, v)) + + +def _deserialize_document_valued_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, Document]: + result: dict[str, Document] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_document(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class DocumentTypeAsMapValueInput: + """Dataclass for DocumentTypeAsMapValueInput structure.""" + + doc_valued_map: dict[str, Document] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.doc_valued_map is not None: + _serialize_document_valued_map( + serializer, + _SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_INPUT.members["docValuedMap"], + self.doc_valued_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["doc_valued_map"] = _deserialize_document_valued_map( + de, + _SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_INPUT.members[ + "docValuedMap" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class DocumentTypeAsMapValueOutput: + """Dataclass for DocumentTypeAsMapValueOutput structure.""" + + doc_valued_map: dict[str, Document] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.doc_valued_map is not None: + _serialize_document_valued_map( + serializer, + _SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_OUTPUT.members["docValuedMap"], + self.doc_valued_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["doc_valued_map"] = _deserialize_document_valued_map( + de, + _SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_OUTPUT.members[ + "docValuedMap" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_OUTPUT, consumer=_consumer + ) + return kwargs + + +DOCUMENT_TYPE_AS_MAP_VALUE = APIOperation( + input=DocumentTypeAsMapValueInput, + output=DocumentTypeAsMapValueOutput, + schema=_SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE, + input_schema=_SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_INPUT, + output_schema=_SCHEMA_DOCUMENT_TYPE_AS_MAP_VALUE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class DocumentTypeAsPayloadInput: + """Dataclass for DocumentTypeAsPayloadInput structure.""" + + document_value: Document | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.document_value is not None: + serializer.write_document( + _SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_INPUT.members["documentValue"], + self.document_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["document_value"] = de.read_document( + _SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_INPUT.members["documentValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class DocumentTypeAsPayloadOutput: + """Dataclass for DocumentTypeAsPayloadOutput structure.""" + + document_value: Document | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.document_value is not None: + serializer.write_document( + _SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_OUTPUT.members["documentValue"], + self.document_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["document_value"] = de.read_document( + _SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_OUTPUT.members["documentValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_OUTPUT, consumer=_consumer + ) + return kwargs + + +DOCUMENT_TYPE_AS_PAYLOAD = APIOperation( + input=DocumentTypeAsPayloadInput, + output=DocumentTypeAsPayloadOutput, + schema=_SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD, + input_schema=_SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_INPUT, + output_schema=_SCHEMA_DOCUMENT_TYPE_AS_PAYLOAD_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class ErrorEvent(ServiceError): + """Dataclass for ErrorEvent structure.""" + + fault: Literal["client", "server"] | None = "client" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ERROR_EVENT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.message is not None: + serializer.write_string( + _SCHEMA_ERROR_EVENT.members["message"], self.message + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["message"] = de.read_string( + _SCHEMA_ERROR_EVENT.members["message"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ERROR_EVENT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class HeadersEvent: + """Dataclass for HeadersEvent structure.""" + + boolean_header: bool | None = None + + byte_header: int | None = None + + short_header: int | None = None + + int_header: int | None = None + + long_header: int | None = None + + blob_header: bytes | None = None + + string_header: str | None = None + + timestamp_header: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HEADERS_EVENT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.boolean_header is not None: + serializer.write_boolean( + _SCHEMA_HEADERS_EVENT.members["booleanHeader"], self.boolean_header + ) + + if self.byte_header is not None: + serializer.write_byte( + _SCHEMA_HEADERS_EVENT.members["byteHeader"], self.byte_header + ) + + if self.short_header is not None: + serializer.write_short( + _SCHEMA_HEADERS_EVENT.members["shortHeader"], self.short_header + ) + + if self.int_header is not None: + serializer.write_integer( + _SCHEMA_HEADERS_EVENT.members["intHeader"], self.int_header + ) + + if self.long_header is not None: + serializer.write_long( + _SCHEMA_HEADERS_EVENT.members["longHeader"], self.long_header + ) + + if self.blob_header is not None: + serializer.write_blob( + _SCHEMA_HEADERS_EVENT.members["blobHeader"], self.blob_header + ) + + if self.string_header is not None: + serializer.write_string( + _SCHEMA_HEADERS_EVENT.members["stringHeader"], self.string_header + ) + + if self.timestamp_header is not None: + serializer.write_timestamp( + _SCHEMA_HEADERS_EVENT.members["timestampHeader"], self.timestamp_header + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["boolean_header"] = de.read_boolean( + _SCHEMA_HEADERS_EVENT.members["booleanHeader"] + ) + + case 1: + kwargs["byte_header"] = de.read_byte( + _SCHEMA_HEADERS_EVENT.members["byteHeader"] + ) + + case 2: + kwargs["short_header"] = de.read_short( + _SCHEMA_HEADERS_EVENT.members["shortHeader"] + ) + + case 3: + kwargs["int_header"] = de.read_integer( + _SCHEMA_HEADERS_EVENT.members["intHeader"] + ) + + case 4: + kwargs["long_header"] = de.read_long( + _SCHEMA_HEADERS_EVENT.members["longHeader"] + ) + + case 5: + kwargs["blob_header"] = de.read_blob( + _SCHEMA_HEADERS_EVENT.members["blobHeader"] + ) + + case 6: + kwargs["string_header"] = de.read_string( + _SCHEMA_HEADERS_EVENT.members["stringHeader"] + ) + + case 7: + kwargs["timestamp_header"] = de.read_timestamp( + _SCHEMA_HEADERS_EVENT.members["timestampHeader"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HEADERS_EVENT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class PayloadStructure: + """Dataclass for PayloadStructure structure.""" + + structure_member: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PAYLOAD_STRUCTURE, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.structure_member is not None: + serializer.write_string( + _SCHEMA_PAYLOAD_STRUCTURE.members["structureMember"], + self.structure_member, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["structure_member"] = de.read_string( + _SCHEMA_PAYLOAD_STRUCTURE.members["structureMember"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_PAYLOAD_STRUCTURE, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class HeadersAndExplicitPayloadEvent: + """Dataclass for HeadersAndExplicitPayloadEvent structure.""" + + header: str | None = None + + payload: PayloadStructure | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HEADERS_AND_EXPLICIT_PAYLOAD_EVENT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.header is not None: + serializer.write_string( + _SCHEMA_HEADERS_AND_EXPLICIT_PAYLOAD_EVENT.members["header"], + self.header, + ) + + if self.payload is not None: + serializer.write_struct( + _SCHEMA_HEADERS_AND_EXPLICIT_PAYLOAD_EVENT.members["payload"], + self.payload, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["header"] = de.read_string( + _SCHEMA_HEADERS_AND_EXPLICIT_PAYLOAD_EVENT.members["header"] + ) + + case 1: + kwargs["payload"] = PayloadStructure.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HEADERS_AND_EXPLICIT_PAYLOAD_EVENT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HeadersAndImplicitPayloadEvent: + """Dataclass for HeadersAndImplicitPayloadEvent structure.""" + + header: str | None = None + + payload: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HEADERS_AND_IMPLICIT_PAYLOAD_EVENT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.header is not None: + serializer.write_string( + _SCHEMA_HEADERS_AND_IMPLICIT_PAYLOAD_EVENT.members["header"], + self.header, + ) + + if self.payload is not None: + serializer.write_string( + _SCHEMA_HEADERS_AND_IMPLICIT_PAYLOAD_EVENT.members["payload"], + self.payload, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["header"] = de.read_string( + _SCHEMA_HEADERS_AND_IMPLICIT_PAYLOAD_EVENT.members["header"] + ) + + case 1: + kwargs["payload"] = de.read_string( + _SCHEMA_HEADERS_AND_IMPLICIT_PAYLOAD_EVENT.members["payload"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HEADERS_AND_IMPLICIT_PAYLOAD_EVENT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class StringPayloadEvent: + """Dataclass for StringPayloadEvent structure.""" + + payload: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STRING_PAYLOAD_EVENT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_string( + _SCHEMA_STRING_PAYLOAD_EVENT.members["payload"], self.payload + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = de.read_string( + _SCHEMA_STRING_PAYLOAD_EVENT.members["payload"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_STRING_PAYLOAD_EVENT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class StructurePayloadEvent: + """Dataclass for StructurePayloadEvent structure.""" + + payload: PayloadStructure | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STRUCTURE_PAYLOAD_EVENT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_struct( + _SCHEMA_STRUCTURE_PAYLOAD_EVENT.members["payload"], self.payload + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = PayloadStructure.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_STRUCTURE_PAYLOAD_EVENT, consumer=_consumer) + return kwargs + + +@dataclass +class PayloadUnionUnionMember: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PAYLOAD_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string( + _SCHEMA_PAYLOAD_UNION.members["unionMember"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_PAYLOAD_UNION.members["unionMember"]) + ) + + +@dataclass +class PayloadUnionUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +PayloadUnion = Union[PayloadUnionUnionMember | PayloadUnionUnknown] + + +class _PayloadUnionDeserializer: + _result: PayloadUnion | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> PayloadUnion: + self._result = None + deserializer.read_struct(_SCHEMA_PAYLOAD_UNION, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(PayloadUnionUnionMember.deserialize(de)) + + case _: + self._set_result(PayloadUnionUnknown(tag=schema.expect_member_name())) + + def _set_result(self, value: PayloadUnion) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class UnionPayloadEvent: + """Dataclass for UnionPayloadEvent structure.""" + + payload: PayloadUnion | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_UNION_PAYLOAD_EVENT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_struct( + _SCHEMA_UNION_PAYLOAD_EVENT.members["payload"], self.payload + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = _PayloadUnionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_UNION_PAYLOAD_EVENT, consumer=_consumer) + return kwargs + + +@dataclass +class EventStreamHeaders: + value: HeadersEvent + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM.members["headers"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=HeadersEvent.deserialize(deserializer)) + + +@dataclass +class EventStreamBlobPayload: + value: BlobPayloadEvent + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM.members["blobPayload"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=BlobPayloadEvent.deserialize(deserializer)) + + +@dataclass +class EventStreamStringPayload: + value: StringPayloadEvent + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_EVENT_STREAM.members["stringPayload"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=StringPayloadEvent.deserialize(deserializer)) + + +@dataclass +class EventStreamStructurePayload: + value: StructurePayloadEvent + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_EVENT_STREAM.members["structurePayload"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=StructurePayloadEvent.deserialize(deserializer)) + + +@dataclass +class EventStreamUnionPayload: + value: UnionPayloadEvent + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_EVENT_STREAM.members["unionPayload"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=UnionPayloadEvent.deserialize(deserializer)) + + +@dataclass +class EventStreamHeadersAndExplicitPayload: + value: HeadersAndExplicitPayloadEvent + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_EVENT_STREAM.members["headersAndExplicitPayload"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=HeadersAndExplicitPayloadEvent.deserialize(deserializer)) + + +@dataclass +class EventStreamHeadersAndImplicitPayload: + value: HeadersAndImplicitPayloadEvent + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_EVENT_STREAM.members["headersAndImplicitPayload"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=HeadersAndImplicitPayloadEvent.deserialize(deserializer)) + + +@dataclass +class EventStreamError: + value: ErrorEvent + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EVENT_STREAM.members["error"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=ErrorEvent.deserialize(deserializer)) + + +@dataclass +class EventStreamUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +EventStream = Union[ + EventStreamHeaders + | EventStreamBlobPayload + | EventStreamStringPayload + | EventStreamStructurePayload + | EventStreamUnionPayload + | EventStreamHeadersAndExplicitPayload + | EventStreamHeadersAndImplicitPayload + | EventStreamError + | EventStreamUnknown +] + + +class _EventStreamDeserializer: + _result: EventStream | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> EventStream: + self._result = None + deserializer.read_struct(_SCHEMA_EVENT_STREAM, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(EventStreamHeaders.deserialize(de)) + + case 1: + self._set_result(EventStreamBlobPayload.deserialize(de)) + + case 2: + self._set_result(EventStreamStringPayload.deserialize(de)) + + case 3: + self._set_result(EventStreamStructurePayload.deserialize(de)) + + case 4: + self._set_result(EventStreamUnionPayload.deserialize(de)) + + case 5: + self._set_result(EventStreamHeadersAndExplicitPayload.deserialize(de)) + + case 6: + self._set_result(EventStreamHeadersAndImplicitPayload.deserialize(de)) + + case 7: + self._set_result(EventStreamError.deserialize(de)) + + case _: + self._set_result(EventStreamUnknown(tag=schema.expect_member_name())) + + def _set_result(self, value: EventStream) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class DuplexStreamInput: + """Dataclass for DuplexStreamInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DUPLEX_STREAM_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DUPLEX_STREAM_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class DuplexStreamOutput: + """Dataclass for DuplexStreamOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DUPLEX_STREAM_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_DUPLEX_STREAM_OUTPUT, consumer=_consumer) + return kwargs + + +DUPLEX_STREAM = APIOperation( + input=DuplexStreamInput, + output=DuplexStreamOutput, + schema=_SCHEMA_DUPLEX_STREAM, + input_schema=_SCHEMA_DUPLEX_STREAM_INPUT, + output_schema=_SCHEMA_DUPLEX_STREAM_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class DuplexStreamWithDistinctStreamsInput: + """Dataclass for DuplexStreamWithDistinctStreamsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class SingletonEvent: + """Dataclass for SingletonEvent structure.""" + + value: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SINGLETON_EVENT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.value is not None: + serializer.write_string( + _SCHEMA_SINGLETON_EVENT.members["value"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = de.read_string( + _SCHEMA_SINGLETON_EVENT.members["value"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_SINGLETON_EVENT, consumer=_consumer) + return kwargs + + +@dataclass +class SingletonEventStreamSingleton: + value: SingletonEvent + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SINGLETON_EVENT_STREAM, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_SINGLETON_EVENT_STREAM.members["singleton"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=SingletonEvent.deserialize(deserializer)) + + +@dataclass +class SingletonEventStreamUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +SingletonEventStream = Union[ + SingletonEventStreamSingleton | SingletonEventStreamUnknown +] + + +class _SingletonEventStreamDeserializer: + _result: SingletonEventStream | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> SingletonEventStream: + self._result = None + deserializer.read_struct(_SCHEMA_SINGLETON_EVENT_STREAM, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(SingletonEventStreamSingleton.deserialize(de)) + + case _: + self._set_result( + SingletonEventStreamUnknown(tag=schema.expect_member_name()) + ) + + def _set_result(self, value: SingletonEventStream) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class DuplexStreamWithDistinctStreamsOutput: + """Dataclass for DuplexStreamWithDistinctStreamsOutput structure.""" + + stream: SingletonEventStream | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.stream is not None: + serializer.write_struct( + _SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS_OUTPUT.members["stream"], + self.stream, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["stream"] = _SingletonEventStreamDeserializer().deserialize( + de + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS_OUTPUT, consumer=_consumer + ) + return kwargs + + +DUPLEX_STREAM_WITH_DISTINCT_STREAMS = APIOperation( + input=DuplexStreamWithDistinctStreamsInput, + output=DuplexStreamWithDistinctStreamsOutput, + schema=_SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS, + input_schema=_SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS_INPUT, + output_schema=_SCHEMA_DUPLEX_STREAM_WITH_DISTINCT_STREAMS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class DuplexStreamWithInitialMessagesInput: + """Dataclass for DuplexStreamWithInitialMessagesInput structure.""" + + initial_request_member: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.initial_request_member is not None: + serializer.write_string( + _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_INPUT.members[ + "initialRequestMember" + ], + self.initial_request_member, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["initial_request_member"] = de.read_string( + _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_INPUT.members[ + "initialRequestMember" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class DuplexStreamWithInitialMessagesOutput: + """Dataclass for DuplexStreamWithInitialMessagesOutput structure.""" + + initial_response_member: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string( + _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_OUTPUT.members[ + "initialResponseMember" + ], + self.initial_response_member, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["initial_response_member"] = de.read_string( + _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_OUTPUT.members[ + "initialResponseMember" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_OUTPUT, consumer=_consumer + ) + if "initial_response_member" not in kwargs: + kwargs["initial_response_member"] = "" + return kwargs + + +@dataclass(kw_only=True) +class ServiceUnavailableError(ServiceError): + """Dataclass for ServiceUnavailableError structure.""" + + fault: Literal["client", "server"] | None = "server" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SERVICE_UNAVAILABLE_ERROR, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.message is not None: + serializer.write_string( + _SCHEMA_SERVICE_UNAVAILABLE_ERROR.members["message"], self.message + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["message"] = de.read_string( + _SCHEMA_SERVICE_UNAVAILABLE_ERROR.members["message"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_SERVICE_UNAVAILABLE_ERROR, consumer=_consumer) + return kwargs + + +DUPLEX_STREAM_WITH_INITIAL_MESSAGES = APIOperation( + input=DuplexStreamWithInitialMessagesInput, + output=DuplexStreamWithInitialMessagesOutput, + schema=_SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES, + input_schema=_SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_INPUT, + output_schema=_SCHEMA_DUPLEX_STREAM_WITH_INITIAL_MESSAGES_OUTPUT, + error_registry=TypeRegistry( + { + ShapeID( + "aws.protocoltests.restjson#ServiceUnavailableError" + ): ServiceUnavailableError + } + ), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[_SCHEMA_SERVICE_UNAVAILABLE_ERROR], +) + + +@dataclass(kw_only=True) +class EmptyInputAndEmptyOutputInput: + """Dataclass for EmptyInputAndEmptyOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class EmptyInputAndEmptyOutputOutput: + """Dataclass for EmptyInputAndEmptyOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, consumer=_consumer + ) + return kwargs + + +EMPTY_INPUT_AND_EMPTY_OUTPUT = APIOperation( + input=EmptyInputAndEmptyOutputInput, + output=EmptyInputAndEmptyOutputOutput, + schema=_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT, + input_schema=_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_INPUT, + output_schema=_SCHEMA_EMPTY_INPUT_AND_EMPTY_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EndpointOperationInput: + """Dataclass for EndpointOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ENDPOINT_OPERATION_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class EndpointOperationOutput: + """Dataclass for EndpointOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_ENDPOINT_OPERATION_OUTPUT, consumer=_consumer) + return kwargs + + +ENDPOINT_OPERATION = APIOperation( + input=EndpointOperationInput, + output=EndpointOperationOutput, + schema=_SCHEMA_ENDPOINT_OPERATION, + input_schema=_SCHEMA_ENDPOINT_OPERATION_INPUT, + output_schema=_SCHEMA_ENDPOINT_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class EndpointWithHostLabelOperationInput: + """Dataclass for EndpointWithHostLabelOperationInput structure.""" + + label: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.label is not None: + serializer.write_string( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT.members["label"], + self.label, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["label"] = de.read_string( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT.members[ + "label" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class EndpointWithHostLabelOperationOutput: + """Dataclass for EndpointWithHostLabelOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +ENDPOINT_WITH_HOST_LABEL_OPERATION = APIOperation( + input=EndpointWithHostLabelOperationInput, + output=EndpointWithHostLabelOperationOutput, + schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION, + input_schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_INPUT, + output_schema=_SCHEMA_ENDPOINT_WITH_HOST_LABEL_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class FooError(ServiceError): + """ + This error has test cases that test some of the dark corners of Amazon + service framework history. It should only be implemented by clients. + """ + + fault: Literal["client", "server"] | None = "server" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FOO_ERROR, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FOO_ERROR, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class FractionalSecondsInput: + """Dataclass for FractionalSecondsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FRACTIONAL_SECONDS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FRACTIONAL_SECONDS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class FractionalSecondsOutput: + """Dataclass for FractionalSecondsOutput structure.""" + + datetime_: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_FRACTIONAL_SECONDS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.datetime_ is not None: + serializer.write_timestamp( + _SCHEMA_FRACTIONAL_SECONDS_OUTPUT.members["datetime"], self.datetime_ + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["datetime_"] = de.read_timestamp( + _SCHEMA_FRACTIONAL_SECONDS_OUTPUT.members["datetime"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_FRACTIONAL_SECONDS_OUTPUT, consumer=_consumer) + return kwargs + + +FRACTIONAL_SECONDS = APIOperation( + input=FractionalSecondsInput, + output=FractionalSecondsOutput, + schema=_SCHEMA_FRACTIONAL_SECONDS, + input_schema=_SCHEMA_FRACTIONAL_SECONDS_INPUT, + output_schema=_SCHEMA_FRACTIONAL_SECONDS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class GreetingWithErrorsInput: + """Dataclass for GreetingWithErrorsInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_WITH_ERRORS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_GREETING_WITH_ERRORS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class GreetingWithErrorsOutput: + """Dataclass for GreetingWithErrorsOutput structure.""" + + greeting: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_GREETING_WITH_ERRORS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.greeting is not None: + serializer.write_string( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT.members["greeting"], self.greeting + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["greeting"] = de.read_string( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT.members["greeting"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_GREETING_WITH_ERRORS_OUTPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class InvalidGreeting(ServiceError): + """This error is thrown when an invalid greeting value is provided.""" + + fault: Literal["client", "server"] | None = "client" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INVALID_GREETING, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.message is not None: + serializer.write_string( + _SCHEMA_INVALID_GREETING.members["Message"], self.message + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["message"] = de.read_string( + _SCHEMA_INVALID_GREETING.members["Message"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_INVALID_GREETING, consumer=_consumer) + return kwargs + + +GREETING_WITH_ERRORS = APIOperation( + input=GreetingWithErrorsInput, + output=GreetingWithErrorsOutput, + schema=_SCHEMA_GREETING_WITH_ERRORS, + input_schema=_SCHEMA_GREETING_WITH_ERRORS_INPUT, + output_schema=_SCHEMA_GREETING_WITH_ERRORS_OUTPUT, + error_registry=TypeRegistry( + { + ShapeID("aws.protocoltests.restjson#InvalidGreeting"): InvalidGreeting, + ShapeID("aws.protocoltests.restjson#ComplexError"): ComplexError, + ShapeID("aws.protocoltests.restjson#FooError"): FooError, + } + ), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[_SCHEMA_INVALID_GREETING, _SCHEMA_COMPLEX_ERROR, _SCHEMA_FOO_ERROR], +) + + +@dataclass(kw_only=True) +class HostWithPathOperationInput: + """Dataclass for HostWithPathOperationInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HostWithPathOperationOutput: + """Dataclass for HostWithPathOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +HOST_WITH_PATH_OPERATION = APIOperation( + input=HostWithPathOperationInput, + output=HostWithPathOperationOutput, + schema=_SCHEMA_HOST_WITH_PATH_OPERATION, + input_schema=_SCHEMA_HOST_WITH_PATH_OPERATION_INPUT, + output_schema=_SCHEMA_HOST_WITH_PATH_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpChecksumRequiredInput: + """Dataclass for HttpChecksumRequiredInput structure.""" + + foo: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_CHECKSUM_REQUIRED_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_HTTP_CHECKSUM_REQUIRED_INPUT.members["foo"], self.foo + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_HTTP_CHECKSUM_REQUIRED_INPUT.members["foo"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_CHECKSUM_REQUIRED_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpChecksumRequiredOutput: + """Dataclass for HttpChecksumRequiredOutput structure.""" + + foo: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_CHECKSUM_REQUIRED_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_HTTP_CHECKSUM_REQUIRED_OUTPUT.members["foo"], self.foo + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_HTTP_CHECKSUM_REQUIRED_OUTPUT.members["foo"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_CHECKSUM_REQUIRED_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_CHECKSUM_REQUIRED = APIOperation( + input=HttpChecksumRequiredInput, + output=HttpChecksumRequiredOutput, + schema=_SCHEMA_HTTP_CHECKSUM_REQUIRED, + input_schema=_SCHEMA_HTTP_CHECKSUM_REQUIRED_INPUT, + output_schema=_SCHEMA_HTTP_CHECKSUM_REQUIRED_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class HttpEmptyPrefixHeadersInput: + """Dataclass for HttpEmptyPrefixHeadersInput structure.""" + + prefix_headers: dict[str, str] | None = None + + specific_header: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.prefix_headers is not None: + _serialize_string_map( + serializer, + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_INPUT.members["prefixHeaders"], + self.prefix_headers, + ) + + if self.specific_header is not None: + serializer.write_string( + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_INPUT.members["specificHeader"], + self.specific_header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["prefix_headers"] = _deserialize_string_map( + de, + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_INPUT.members[ + "prefixHeaders" + ], + ) + + case 1: + kwargs["specific_header"] = de.read_string( + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_INPUT.members[ + "specificHeader" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpEmptyPrefixHeadersOutput: + """Dataclass for HttpEmptyPrefixHeadersOutput structure.""" + + prefix_headers: dict[str, str] | None = None + + specific_header: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.prefix_headers is not None: + _serialize_string_map( + serializer, + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_OUTPUT.members["prefixHeaders"], + self.prefix_headers, + ) + + if self.specific_header is not None: + serializer.write_string( + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_OUTPUT.members["specificHeader"], + self.specific_header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["prefix_headers"] = _deserialize_string_map( + de, + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_OUTPUT.members[ + "prefixHeaders" + ], + ) + + case 1: + kwargs["specific_header"] = de.read_string( + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_OUTPUT.members[ + "specificHeader" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_EMPTY_PREFIX_HEADERS = APIOperation( + input=HttpEmptyPrefixHeadersInput, + output=HttpEmptyPrefixHeadersOutput, + schema=_SCHEMA_HTTP_EMPTY_PREFIX_HEADERS, + input_schema=_SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_INPUT, + output_schema=_SCHEMA_HTTP_EMPTY_PREFIX_HEADERS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +class StringEnum(UnknownEnumMixin, StrEnum): + V = "enumvalue" + + +@dataclass(kw_only=True) +class HttpEnumPayloadInput: + """Dataclass for HttpEnumPayloadInput structure.""" + + payload: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_ENUM_PAYLOAD_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_string( + _SCHEMA_HTTP_ENUM_PAYLOAD_INPUT.members["payload"], self.payload + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = StringEnum( + de.read_string( + _SCHEMA_HTTP_ENUM_PAYLOAD_INPUT.members["payload"] + ) + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_ENUM_PAYLOAD_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class HttpEnumPayloadOutput: + """Dataclass for HttpEnumPayloadOutput structure.""" + + payload: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_ENUM_PAYLOAD_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_string( + _SCHEMA_HTTP_ENUM_PAYLOAD_OUTPUT.members["payload"], self.payload + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = StringEnum( + de.read_string( + _SCHEMA_HTTP_ENUM_PAYLOAD_OUTPUT.members["payload"] + ) + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_ENUM_PAYLOAD_OUTPUT, consumer=_consumer) + return kwargs + + +HTTP_ENUM_PAYLOAD = APIOperation( + input=HttpEnumPayloadInput, + output=HttpEnumPayloadOutput, + schema=_SCHEMA_HTTP_ENUM_PAYLOAD, + input_schema=_SCHEMA_HTTP_ENUM_PAYLOAD_INPUT, + output_schema=_SCHEMA_HTTP_ENUM_PAYLOAD_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpPayloadTraitsInput: + """Dataclass for HttpPayloadTraitsInput structure.""" + + foo: str | None = None + + blob: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PAYLOAD_TRAITS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_HTTP_PAYLOAD_TRAITS_INPUT.members["foo"], self.foo + ) + + if self.blob is not None: + serializer.write_blob( + _SCHEMA_HTTP_PAYLOAD_TRAITS_INPUT.members["blob"], self.blob + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_HTTP_PAYLOAD_TRAITS_INPUT.members["foo"] + ) + + case 1: + kwargs["blob"] = de.read_blob( + _SCHEMA_HTTP_PAYLOAD_TRAITS_INPUT.members["blob"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_PAYLOAD_TRAITS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class HttpPayloadTraitsOutput: + """Dataclass for HttpPayloadTraitsOutput structure.""" + + foo: str | None = None + + blob: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PAYLOAD_TRAITS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_HTTP_PAYLOAD_TRAITS_OUTPUT.members["foo"], self.foo + ) + + if self.blob is not None: + serializer.write_blob( + _SCHEMA_HTTP_PAYLOAD_TRAITS_OUTPUT.members["blob"], self.blob + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_HTTP_PAYLOAD_TRAITS_OUTPUT.members["foo"] + ) + + case 1: + kwargs["blob"] = de.read_blob( + _SCHEMA_HTTP_PAYLOAD_TRAITS_OUTPUT.members["blob"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_PAYLOAD_TRAITS_OUTPUT, consumer=_consumer) + return kwargs + + +HTTP_PAYLOAD_TRAITS = APIOperation( + input=HttpPayloadTraitsInput, + output=HttpPayloadTraitsOutput, + schema=_SCHEMA_HTTP_PAYLOAD_TRAITS, + input_schema=_SCHEMA_HTTP_PAYLOAD_TRAITS_INPUT, + output_schema=_SCHEMA_HTTP_PAYLOAD_TRAITS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpPayloadTraitsWithMediaTypeInput: + """Dataclass for HttpPayloadTraitsWithMediaTypeInput structure.""" + + foo: str | None = None + + blob: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT.members["foo"], + self.foo, + ) + + if self.blob is not None: + serializer.write_blob( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT.members["blob"], + self.blob, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT.members["foo"] + ) + + case 1: + kwargs["blob"] = de.read_blob( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT.members[ + "blob" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpPayloadTraitsWithMediaTypeOutput: + """Dataclass for HttpPayloadTraitsWithMediaTypeOutput structure.""" + + foo: str | None = None + + blob: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT.members["foo"], + self.foo, + ) + + if self.blob is not None: + serializer.write_blob( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT.members["blob"], + self.blob, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT.members[ + "foo" + ] + ) + + case 1: + kwargs["blob"] = de.read_blob( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT.members[ + "blob" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE = APIOperation( + input=HttpPayloadTraitsWithMediaTypeInput, + output=HttpPayloadTraitsWithMediaTypeOutput, + schema=_SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE, + input_schema=_SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_INPUT, + output_schema=_SCHEMA_HTTP_PAYLOAD_TRAITS_WITH_MEDIA_TYPE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NestedPayload: + """Dataclass for NestedPayload structure.""" + + greeting: str | None = None + + name: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NESTED_PAYLOAD, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.greeting is not None: + serializer.write_string( + _SCHEMA_NESTED_PAYLOAD.members["greeting"], self.greeting + ) + + if self.name is not None: + serializer.write_string(_SCHEMA_NESTED_PAYLOAD.members["name"], self.name) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["greeting"] = de.read_string( + _SCHEMA_NESTED_PAYLOAD.members["greeting"] + ) + + case 1: + kwargs["name"] = de.read_string( + _SCHEMA_NESTED_PAYLOAD.members["name"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NESTED_PAYLOAD, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class HttpPayloadWithStructureInput: + """Dataclass for HttpPayloadWithStructureInput structure.""" + + nested: NestedPayload | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.nested is not None: + serializer.write_struct( + _SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_INPUT.members["nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["nested"] = NestedPayload.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpPayloadWithStructureOutput: + """Dataclass for HttpPayloadWithStructureOutput structure.""" + + nested: NestedPayload | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.nested is not None: + serializer.write_struct( + _SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_OUTPUT.members["nested"], + self.nested, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["nested"] = NestedPayload.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_PAYLOAD_WITH_STRUCTURE = APIOperation( + input=HttpPayloadWithStructureInput, + output=HttpPayloadWithStructureOutput, + schema=_SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE, + input_schema=_SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_INPUT, + output_schema=_SCHEMA_HTTP_PAYLOAD_WITH_STRUCTURE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass +class UnionPayloadGreeting: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_UNION_PAYLOAD, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_UNION_PAYLOAD.members["greeting"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_UNION_PAYLOAD.members["greeting"]) + ) + + +@dataclass +class UnionPayloadUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +UnionPayload = Union[UnionPayloadGreeting | UnionPayloadUnknown] + + +class _UnionPayloadDeserializer: + _result: UnionPayload | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> UnionPayload: + self._result = None + deserializer.read_struct(_SCHEMA_UNION_PAYLOAD, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(UnionPayloadGreeting.deserialize(de)) + + case _: + self._set_result(UnionPayloadUnknown(tag=schema.expect_member_name())) + + def _set_result(self, value: UnionPayload) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class HttpPayloadWithUnionInput: + """Dataclass for HttpPayloadWithUnionInput structure.""" + + nested: UnionPayload | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PAYLOAD_WITH_UNION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.nested is not None: + serializer.write_struct( + _SCHEMA_HTTP_PAYLOAD_WITH_UNION_INPUT.members["nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["nested"] = _UnionPayloadDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_PAYLOAD_WITH_UNION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpPayloadWithUnionOutput: + """Dataclass for HttpPayloadWithUnionOutput structure.""" + + nested: UnionPayload | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PAYLOAD_WITH_UNION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.nested is not None: + serializer.write_struct( + _SCHEMA_HTTP_PAYLOAD_WITH_UNION_OUTPUT.members["nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["nested"] = _UnionPayloadDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_PAYLOAD_WITH_UNION_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_PAYLOAD_WITH_UNION = APIOperation( + input=HttpPayloadWithUnionInput, + output=HttpPayloadWithUnionOutput, + schema=_SCHEMA_HTTP_PAYLOAD_WITH_UNION, + input_schema=_SCHEMA_HTTP_PAYLOAD_WITH_UNION_INPUT, + output_schema=_SCHEMA_HTTP_PAYLOAD_WITH_UNION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpPrefixHeadersInput: + """Dataclass for HttpPrefixHeadersInput structure.""" + + foo: str | None = None + + foo_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PREFIX_HEADERS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_HTTP_PREFIX_HEADERS_INPUT.members["foo"], self.foo + ) + + if self.foo_map is not None: + _serialize_string_map( + serializer, + _SCHEMA_HTTP_PREFIX_HEADERS_INPUT.members["fooMap"], + self.foo_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_HTTP_PREFIX_HEADERS_INPUT.members["foo"] + ) + + case 1: + kwargs["foo_map"] = _deserialize_string_map( + de, _SCHEMA_HTTP_PREFIX_HEADERS_INPUT.members["fooMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_PREFIX_HEADERS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class HttpPrefixHeadersOutput: + """Dataclass for HttpPrefixHeadersOutput structure.""" + + foo: str | None = None + + foo_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PREFIX_HEADERS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_HTTP_PREFIX_HEADERS_OUTPUT.members["foo"], self.foo + ) + + if self.foo_map is not None: + _serialize_string_map( + serializer, + _SCHEMA_HTTP_PREFIX_HEADERS_OUTPUT.members["fooMap"], + self.foo_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_HTTP_PREFIX_HEADERS_OUTPUT.members["foo"] + ) + + case 1: + kwargs["foo_map"] = _deserialize_string_map( + de, _SCHEMA_HTTP_PREFIX_HEADERS_OUTPUT.members["fooMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_PREFIX_HEADERS_OUTPUT, consumer=_consumer) + return kwargs + + +HTTP_PREFIX_HEADERS = APIOperation( + input=HttpPrefixHeadersInput, + output=HttpPrefixHeadersOutput, + schema=_SCHEMA_HTTP_PREFIX_HEADERS, + input_schema=_SCHEMA_HTTP_PREFIX_HEADERS_INPUT, + output_schema=_SCHEMA_HTTP_PREFIX_HEADERS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpPrefixHeadersInResponseInput: + """Dataclass for HttpPrefixHeadersInResponseInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpPrefixHeadersInResponseOutput: + """Dataclass for HttpPrefixHeadersInResponseOutput structure.""" + + prefix_headers: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.prefix_headers is not None: + _serialize_string_map( + serializer, + _SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_OUTPUT.members["prefixHeaders"], + self.prefix_headers, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["prefix_headers"] = _deserialize_string_map( + de, + _SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_OUTPUT.members[ + "prefixHeaders" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_PREFIX_HEADERS_IN_RESPONSE = APIOperation( + input=HttpPrefixHeadersInResponseInput, + output=HttpPrefixHeadersInResponseOutput, + schema=_SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE, + input_schema=_SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_INPUT, + output_schema=_SCHEMA_HTTP_PREFIX_HEADERS_IN_RESPONSE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_query_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_query_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class HttpQueryParamsOnlyOperationInput: + """Dataclass for HttpQueryParamsOnlyOperationInput structure.""" + + query_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.query_map is not None: + _serialize_query_map( + serializer, + _SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_INPUT.members["queryMap"], + self.query_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["query_map"] = _deserialize_query_map( + de, + _SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_INPUT.members[ + "queryMap" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpQueryParamsOnlyOperationOutput: + """Dataclass for HttpQueryParamsOnlyOperationOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_QUERY_PARAMS_ONLY_OPERATION = APIOperation( + input=HttpQueryParamsOnlyOperationInput, + output=HttpQueryParamsOnlyOperationOutput, + schema=_SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION, + input_schema=_SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_INPUT, + output_schema=_SCHEMA_HTTP_QUERY_PARAMS_ONLY_OPERATION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpRequestWithFloatLabelsInput: + """Dataclass for HttpRequestWithFloatLabelsInput structure.""" + + float_: float | None = None + + double: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.float_ is not None: + serializer.write_float( + _SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT.members["float"], + self.float_, + ) + + if self.double is not None: + serializer.write_double( + _SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT.members["double"], + self.double, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["float_"] = de.read_float( + _SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT.members["float"] + ) + + case 1: + kwargs["double"] = de.read_double( + _SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT.members["double"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpRequestWithFloatLabelsOutput: + """Dataclass for HttpRequestWithFloatLabelsOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_REQUEST_WITH_FLOAT_LABELS = APIOperation( + input=HttpRequestWithFloatLabelsInput, + output=HttpRequestWithFloatLabelsOutput, + schema=_SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS, + input_schema=_SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_INPUT, + output_schema=_SCHEMA_HTTP_REQUEST_WITH_FLOAT_LABELS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpRequestWithGreedyLabelInPathInput: + """Dataclass for HttpRequestWithGreedyLabelInPathInput structure.""" + + foo: str | None = None + + baz: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT.members["foo"], + self.foo, + ) + + if self.baz is not None: + serializer.write_string( + _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT.members["baz"], + self.baz, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT.members[ + "foo" + ] + ) + + case 1: + kwargs["baz"] = de.read_string( + _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT.members[ + "baz" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpRequestWithGreedyLabelInPathOutput: + """Dataclass for HttpRequestWithGreedyLabelInPathOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH = APIOperation( + input=HttpRequestWithGreedyLabelInPathInput, + output=HttpRequestWithGreedyLabelInPathOutput, + schema=_SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH, + input_schema=_SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_INPUT, + output_schema=_SCHEMA_HTTP_REQUEST_WITH_GREEDY_LABEL_IN_PATH_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpRequestWithLabelsInput: + """Dataclass for HttpRequestWithLabelsInput structure.""" + + string: str | None = None + + short: int | None = None + + integer: int | None = None + + long: int | None = None + + float_: float | None = None + + double: float | None = None + + boolean: bool | None = None + """Serialized in the path as true or false.""" + + timestamp: datetime | None = None + """ + Note that this member has no format, so it's serialized as an RFC 3399 + date-time. + """ + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string is not None: + serializer.write_string( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["string"], self.string + ) + + if self.short is not None: + serializer.write_short( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["short"], self.short + ) + + if self.integer is not None: + serializer.write_integer( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["integer"], self.integer + ) + + if self.long is not None: + serializer.write_long( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["long"], self.long + ) + + if self.float_ is not None: + serializer.write_float( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["float"], self.float_ + ) + + if self.double is not None: + serializer.write_double( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["double"], self.double + ) + + if self.boolean is not None: + serializer.write_boolean( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["boolean"], self.boolean + ) + + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string"] = de.read_string( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["string"] + ) + + case 1: + kwargs["short"] = de.read_short( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["short"] + ) + + case 2: + kwargs["integer"] = de.read_integer( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["integer"] + ) + + case 3: + kwargs["long"] = de.read_long( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["long"] + ) + + case 4: + kwargs["float_"] = de.read_float( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["float"] + ) + + case 5: + kwargs["double"] = de.read_double( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["double"] + ) + + case 6: + kwargs["boolean"] = de.read_boolean( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["boolean"] + ) + + case 7: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT.members["timestamp"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpRequestWithLabelsOutput: + """Dataclass for HttpRequestWithLabelsOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_REQUEST_WITH_LABELS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_REQUEST_WITH_LABELS = APIOperation( + input=HttpRequestWithLabelsInput, + output=HttpRequestWithLabelsOutput, + schema=_SCHEMA_HTTP_REQUEST_WITH_LABELS, + input_schema=_SCHEMA_HTTP_REQUEST_WITH_LABELS_INPUT, + output_schema=_SCHEMA_HTTP_REQUEST_WITH_LABELS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpRequestWithLabelsAndTimestampFormatInput: + """Dataclass for HttpRequestWithLabelsAndTimestampFormatInput structure.""" + + member_epoch_seconds: datetime | None = None + + member_http_date: datetime | None = None + + member_date_time: datetime | None = None + + default_format: datetime | None = None + + target_epoch_seconds: datetime | None = None + + target_http_date: datetime | None = None + + target_date_time: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.member_epoch_seconds is not None: + serializer.write_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "memberEpochSeconds" + ], + self.member_epoch_seconds, + ) + + if self.member_http_date is not None: + serializer.write_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "memberHttpDate" + ], + self.member_http_date, + ) + + if self.member_date_time is not None: + serializer.write_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "memberDateTime" + ], + self.member_date_time, + ) + + if self.default_format is not None: + serializer.write_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "defaultFormat" + ], + self.default_format, + ) + + if self.target_epoch_seconds is not None: + serializer.write_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "targetEpochSeconds" + ], + self.target_epoch_seconds, + ) + + if self.target_http_date is not None: + serializer.write_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "targetHttpDate" + ], + self.target_http_date, + ) + + if self.target_date_time is not None: + serializer.write_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "targetDateTime" + ], + self.target_date_time, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["member_epoch_seconds"] = de.read_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "memberEpochSeconds" + ] + ) + + case 1: + kwargs["member_http_date"] = de.read_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "memberHttpDate" + ] + ) + + case 2: + kwargs["member_date_time"] = de.read_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "memberDateTime" + ] + ) + + case 3: + kwargs["default_format"] = de.read_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "defaultFormat" + ] + ) + + case 4: + kwargs["target_epoch_seconds"] = de.read_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "targetEpochSeconds" + ] + ) + + case 5: + kwargs["target_http_date"] = de.read_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "targetHttpDate" + ] + ) + + case 6: + kwargs["target_date_time"] = de.read_timestamp( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT.members[ + "targetDateTime" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT, + consumer=_consumer, + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpRequestWithLabelsAndTimestampFormatOutput: + """Dataclass for HttpRequestWithLabelsAndTimestampFormatOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_OUTPUT, + consumer=_consumer, + ) + return kwargs + + +HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT = APIOperation( + input=HttpRequestWithLabelsAndTimestampFormatInput, + output=HttpRequestWithLabelsAndTimestampFormatOutput, + schema=_SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT, + input_schema=_SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_INPUT, + output_schema=_SCHEMA_HTTP_REQUEST_WITH_LABELS_AND_TIMESTAMP_FORMAT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpRequestWithRegexLiteralInput: + """Dataclass for HttpRequestWithRegexLiteralInput structure.""" + + str_: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.str_ is not None: + serializer.write_string( + _SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_INPUT.members["str"], self.str_ + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["str_"] = de.read_string( + _SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_INPUT.members["str"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class HttpRequestWithRegexLiteralOutput: + """Dataclass for HttpRequestWithRegexLiteralOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_OUTPUT, consumer=_consumer + ) + return kwargs + + +HTTP_REQUEST_WITH_REGEX_LITERAL = APIOperation( + input=HttpRequestWithRegexLiteralInput, + output=HttpRequestWithRegexLiteralOutput, + schema=_SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL, + input_schema=_SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_INPUT, + output_schema=_SCHEMA_HTTP_REQUEST_WITH_REGEX_LITERAL_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpResponseCodeInput: + """Dataclass for HttpResponseCodeInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_RESPONSE_CODE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_RESPONSE_CODE_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class HttpResponseCodeOutput: + """Dataclass for HttpResponseCodeOutput structure.""" + + status: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_RESPONSE_CODE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.status is not None: + serializer.write_integer( + _SCHEMA_HTTP_RESPONSE_CODE_OUTPUT.members["Status"], self.status + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["status"] = de.read_integer( + _SCHEMA_HTTP_RESPONSE_CODE_OUTPUT.members["Status"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_RESPONSE_CODE_OUTPUT, consumer=_consumer) + return kwargs + + +HTTP_RESPONSE_CODE = APIOperation( + input=HttpResponseCodeInput, + output=HttpResponseCodeOutput, + schema=_SCHEMA_HTTP_RESPONSE_CODE, + input_schema=_SCHEMA_HTTP_RESPONSE_CODE_INPUT, + output_schema=_SCHEMA_HTTP_RESPONSE_CODE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class HttpStringPayloadInput: + """Dataclass for HttpStringPayloadInput structure.""" + + payload: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_STRING_PAYLOAD_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_string( + _SCHEMA_HTTP_STRING_PAYLOAD_INPUT.members["payload"], self.payload + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = de.read_string( + _SCHEMA_HTTP_STRING_PAYLOAD_INPUT.members["payload"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_STRING_PAYLOAD_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class HttpStringPayloadOutput: + """Dataclass for HttpStringPayloadOutput structure.""" + + payload: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_HTTP_STRING_PAYLOAD_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_string( + _SCHEMA_HTTP_STRING_PAYLOAD_OUTPUT.members["payload"], self.payload + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = de.read_string( + _SCHEMA_HTTP_STRING_PAYLOAD_OUTPUT.members["payload"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_HTTP_STRING_PAYLOAD_OUTPUT, consumer=_consumer) + return kwargs + + +HTTP_STRING_PAYLOAD = APIOperation( + input=HttpStringPayloadInput, + output=HttpStringPayloadOutput, + schema=_SCHEMA_HTTP_STRING_PAYLOAD, + input_schema=_SCHEMA_HTTP_STRING_PAYLOAD_INPUT, + output_schema=_SCHEMA_HTTP_STRING_PAYLOAD_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class IgnoreQueryParamsInResponseInput: + """Dataclass for IgnoreQueryParamsInResponseInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class IgnoreQueryParamsInResponseOutput: + """Dataclass for IgnoreQueryParamsInResponseOutput structure.""" + + baz: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.baz is not None: + serializer.write_string( + _SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_OUTPUT.members["baz"], self.baz + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["baz"] = de.read_string( + _SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_OUTPUT.members["baz"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_OUTPUT, consumer=_consumer + ) + return kwargs + + +IGNORE_QUERY_PARAMS_IN_RESPONSE = APIOperation( + input=IgnoreQueryParamsInResponseInput, + output=IgnoreQueryParamsInResponseOutput, + schema=_SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE, + input_schema=_SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_INPUT, + output_schema=_SCHEMA_IGNORE_QUERY_PARAMS_IN_RESPONSE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class InputAndOutputWithHeadersInput: + """Dataclass for InputAndOutputWithHeadersInput structure.""" + + header_string: str | None = None + + header_byte: int | None = None + + header_short: int | None = None + + header_integer: int | None = None + + header_long: int | None = None + + header_float: float | None = None + + header_double: float | None = None + + header_true_bool: bool | None = None + + header_false_bool: bool | None = None + + header_string_list: list[str] | None = None + + header_string_set: list[str] | None = None + + header_integer_list: list[int] | None = None + + header_boolean_list: list[bool] | None = None + + header_timestamp_list: list[datetime] | None = None + + header_enum: str | None = None + + header_enum_list: list[str] | None = None + + header_integer_enum: int | None = None + + header_integer_enum_list: list[int] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.header_string is not None: + serializer.write_string( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerString"], + self.header_string, + ) + + if self.header_byte is not None: + serializer.write_byte( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerByte"], + self.header_byte, + ) + + if self.header_short is not None: + serializer.write_short( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerShort"], + self.header_short, + ) + + if self.header_integer is not None: + serializer.write_integer( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerInteger"], + self.header_integer, + ) + + if self.header_long is not None: + serializer.write_long( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerLong"], + self.header_long, + ) + + if self.header_float is not None: + serializer.write_float( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerFloat"], + self.header_float, + ) + + if self.header_double is not None: + serializer.write_double( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerDouble"], + self.header_double, + ) + + if self.header_true_bool is not None: + serializer.write_boolean( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerTrueBool"], + self.header_true_bool, + ) + + if self.header_false_bool is not None: + serializer.write_boolean( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerFalseBool"], + self.header_false_bool, + ) + + if self.header_string_list is not None: + _serialize_string_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerStringList"], + self.header_string_list, + ) + + if self.header_string_set is not None: + _serialize_string_set( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerStringSet"], + self.header_string_set, + ) + + if self.header_integer_list is not None: + _serialize_integer_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerIntegerList" + ], + self.header_integer_list, + ) + + if self.header_boolean_list is not None: + _serialize_boolean_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerBooleanList" + ], + self.header_boolean_list, + ) + + if self.header_timestamp_list is not None: + _serialize_timestamp_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerTimestampList" + ], + self.header_timestamp_list, + ) + + if self.header_enum is not None: + serializer.write_string( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerEnum"], + self.header_enum, + ) + + if self.header_enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members["headerEnumList"], + self.header_enum_list, + ) + + if self.header_integer_enum is not None: + serializer.write_integer( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerIntegerEnum" + ], + self.header_integer_enum, + ) + + if self.header_integer_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerIntegerEnumList" + ], + self.header_integer_enum_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["header_string"] = de.read_string( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerString" + ] + ) + + case 1: + kwargs["header_byte"] = de.read_byte( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerByte" + ] + ) + + case 2: + kwargs["header_short"] = de.read_short( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerShort" + ] + ) + + case 3: + kwargs["header_integer"] = de.read_integer( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerInteger" + ] + ) + + case 4: + kwargs["header_long"] = de.read_long( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerLong" + ] + ) + + case 5: + kwargs["header_float"] = de.read_float( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerFloat" + ] + ) + + case 6: + kwargs["header_double"] = de.read_double( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerDouble" + ] + ) + + case 7: + kwargs["header_true_bool"] = de.read_boolean( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerTrueBool" + ] + ) + + case 8: + kwargs["header_false_bool"] = de.read_boolean( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerFalseBool" + ] + ) + + case 9: + kwargs["header_string_list"] = _deserialize_string_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerStringList" + ], + ) + + case 10: + kwargs["header_string_set"] = _deserialize_string_set( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerStringSet" + ], + ) + + case 11: + kwargs["header_integer_list"] = _deserialize_integer_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerIntegerList" + ], + ) + + case 12: + kwargs["header_boolean_list"] = _deserialize_boolean_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerBooleanList" + ], + ) + + case 13: + kwargs["header_timestamp_list"] = _deserialize_timestamp_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerTimestampList" + ], + ) + + case 14: + kwargs["header_enum"] = FooEnum( + de.read_string( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerEnum" + ] + ) + ) + + case 15: + kwargs["header_enum_list"] = _deserialize_foo_enum_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerEnumList" + ], + ) + + case 16: + kwargs["header_integer_enum"] = IntegerEnum( + de.read_integer( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerIntegerEnum" + ] + ) + ) + + case 17: + kwargs["header_integer_enum_list"] = _deserialize_integer_enum_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT.members[ + "headerIntegerEnumList" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class InputAndOutputWithHeadersOutput: + """Dataclass for InputAndOutputWithHeadersOutput structure.""" + + header_string: str | None = None + + header_byte: int | None = None + + header_short: int | None = None + + header_integer: int | None = None + + header_long: int | None = None + + header_float: float | None = None + + header_double: float | None = None + + header_true_bool: bool | None = None + + header_false_bool: bool | None = None + + header_string_list: list[str] | None = None + + header_string_set: list[str] | None = None + + header_integer_list: list[int] | None = None + + header_boolean_list: list[bool] | None = None + + header_timestamp_list: list[datetime] | None = None + + header_enum: str | None = None + + header_enum_list: list[str] | None = None + + header_integer_enum: int | None = None + + header_integer_enum_list: list[int] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.header_string is not None: + serializer.write_string( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerString"], + self.header_string, + ) + + if self.header_byte is not None: + serializer.write_byte( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerByte"], + self.header_byte, + ) + + if self.header_short is not None: + serializer.write_short( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerShort"], + self.header_short, + ) + + if self.header_integer is not None: + serializer.write_integer( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerInteger"], + self.header_integer, + ) + + if self.header_long is not None: + serializer.write_long( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerLong"], + self.header_long, + ) + + if self.header_float is not None: + serializer.write_float( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerFloat"], + self.header_float, + ) + + if self.header_double is not None: + serializer.write_double( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerDouble"], + self.header_double, + ) + + if self.header_true_bool is not None: + serializer.write_boolean( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerTrueBool"], + self.header_true_bool, + ) + + if self.header_false_bool is not None: + serializer.write_boolean( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerFalseBool"], + self.header_false_bool, + ) + + if self.header_string_list is not None: + _serialize_string_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerStringList" + ], + self.header_string_list, + ) + + if self.header_string_set is not None: + _serialize_string_set( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerStringSet"], + self.header_string_set, + ) + + if self.header_integer_list is not None: + _serialize_integer_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerIntegerList" + ], + self.header_integer_list, + ) + + if self.header_boolean_list is not None: + _serialize_boolean_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerBooleanList" + ], + self.header_boolean_list, + ) + + if self.header_timestamp_list is not None: + _serialize_timestamp_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerTimestampList" + ], + self.header_timestamp_list, + ) + + if self.header_enum is not None: + serializer.write_string( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerEnum"], + self.header_enum, + ) + + if self.header_enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members["headerEnumList"], + self.header_enum_list, + ) + + if self.header_integer_enum is not None: + serializer.write_integer( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerIntegerEnum" + ], + self.header_integer_enum, + ) + + if self.header_integer_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerIntegerEnumList" + ], + self.header_integer_enum_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["header_string"] = de.read_string( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerString" + ] + ) + + case 1: + kwargs["header_byte"] = de.read_byte( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerByte" + ] + ) + + case 2: + kwargs["header_short"] = de.read_short( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerShort" + ] + ) + + case 3: + kwargs["header_integer"] = de.read_integer( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerInteger" + ] + ) + + case 4: + kwargs["header_long"] = de.read_long( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerLong" + ] + ) + + case 5: + kwargs["header_float"] = de.read_float( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerFloat" + ] + ) + + case 6: + kwargs["header_double"] = de.read_double( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerDouble" + ] + ) + + case 7: + kwargs["header_true_bool"] = de.read_boolean( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerTrueBool" + ] + ) + + case 8: + kwargs["header_false_bool"] = de.read_boolean( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerFalseBool" + ] + ) + + case 9: + kwargs["header_string_list"] = _deserialize_string_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerStringList" + ], + ) + + case 10: + kwargs["header_string_set"] = _deserialize_string_set( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerStringSet" + ], + ) + + case 11: + kwargs["header_integer_list"] = _deserialize_integer_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerIntegerList" + ], + ) + + case 12: + kwargs["header_boolean_list"] = _deserialize_boolean_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerBooleanList" + ], + ) + + case 13: + kwargs["header_timestamp_list"] = _deserialize_timestamp_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerTimestampList" + ], + ) + + case 14: + kwargs["header_enum"] = FooEnum( + de.read_string( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerEnum" + ] + ) + ) + + case 15: + kwargs["header_enum_list"] = _deserialize_foo_enum_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerEnumList" + ], + ) + + case 16: + kwargs["header_integer_enum"] = IntegerEnum( + de.read_integer( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerIntegerEnum" + ] + ) + ) + + case 17: + kwargs["header_integer_enum_list"] = _deserialize_integer_enum_list( + de, + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT.members[ + "headerIntegerEnumList" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT, consumer=_consumer + ) + return kwargs + + +INPUT_AND_OUTPUT_WITH_HEADERS = APIOperation( + input=InputAndOutputWithHeadersInput, + output=InputAndOutputWithHeadersOutput, + schema=_SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS, + input_schema=_SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_INPUT, + output_schema=_SCHEMA_INPUT_AND_OUTPUT_WITH_HEADERS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class InputStreamInput: + """Dataclass for InputStreamInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INPUT_STREAM_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_INPUT_STREAM_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class InputStreamOutput: + """Dataclass for InputStreamOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INPUT_STREAM_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_INPUT_STREAM_OUTPUT, consumer=_consumer) + return kwargs + + +INPUT_STREAM = APIOperation( + input=InputStreamInput, + output=InputStreamOutput, + schema=_SCHEMA_INPUT_STREAM, + input_schema=_SCHEMA_INPUT_STREAM_INPUT, + output_schema=_SCHEMA_INPUT_STREAM_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class InputStreamWithInitialRequestInput: + """Dataclass for InputStreamWithInitialRequestInput structure.""" + + initial_request_member: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.initial_request_member is not None: + serializer.write_string( + _SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_INPUT.members[ + "initialRequestMember" + ], + self.initial_request_member, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["initial_request_member"] = de.read_string( + _SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_INPUT.members[ + "initialRequestMember" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class InputStreamWithInitialRequestOutput: + """Dataclass for InputStreamWithInitialRequestOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_OUTPUT, consumer=_consumer + ) + return kwargs + + +INPUT_STREAM_WITH_INITIAL_REQUEST = APIOperation( + input=InputStreamWithInitialRequestInput, + output=InputStreamWithInitialRequestOutput, + schema=_SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST, + input_schema=_SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_INPUT, + output_schema=_SCHEMA_INPUT_STREAM_WITH_INITIAL_REQUEST_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class JsonBlobsInput: + """Dataclass for JsonBlobsInput structure.""" + + data: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_BLOBS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.data is not None: + serializer.write_blob(_SCHEMA_JSON_BLOBS_INPUT.members["data"], self.data) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["data"] = de.read_blob( + _SCHEMA_JSON_BLOBS_INPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_BLOBS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonBlobsOutput: + """Dataclass for JsonBlobsOutput structure.""" + + data: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_BLOBS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.data is not None: + serializer.write_blob(_SCHEMA_JSON_BLOBS_OUTPUT.members["data"], self.data) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["data"] = de.read_blob( + _SCHEMA_JSON_BLOBS_OUTPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_BLOBS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_BLOBS = APIOperation( + input=JsonBlobsInput, + output=JsonBlobsOutput, + schema=_SCHEMA_JSON_BLOBS, + input_schema=_SCHEMA_JSON_BLOBS_INPUT, + output_schema=_SCHEMA_JSON_BLOBS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_foo_enum_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_foo_enum_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = FooEnum(d.read_string(value_schema)) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_foo_enum_set( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_foo_enum_set( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(FooEnum(d.read_string(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class JsonEnumsInput: + """Dataclass for JsonEnumsInput structure.""" + + foo_enum1: str | None = None + + foo_enum2: str | None = None + + foo_enum3: str | None = None + + foo_enum_list: list[str] | None = None + + foo_enum_set: list[str] | None = None + + foo_enum_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_ENUMS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo_enum1 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnum1"], self.foo_enum1 + ) + + if self.foo_enum2 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnum2"], self.foo_enum2 + ) + + if self.foo_enum3 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnum3"], self.foo_enum3 + ) + + if self.foo_enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumList"], + self.foo_enum_list, + ) + + if self.foo_enum_set is not None: + _serialize_foo_enum_set( + serializer, + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumSet"], + self.foo_enum_set, + ) + + if self.foo_enum_map is not None: + _serialize_foo_enum_map( + serializer, + _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumMap"], + self.foo_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo_enum1"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_INPUT.members["fooEnum1"]) + ) + + case 1: + kwargs["foo_enum2"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_INPUT.members["fooEnum2"]) + ) + + case 2: + kwargs["foo_enum3"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_INPUT.members["fooEnum3"]) + ) + + case 3: + kwargs["foo_enum_list"] = _deserialize_foo_enum_list( + de, _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumList"] + ) + + case 4: + kwargs["foo_enum_set"] = _deserialize_foo_enum_set( + de, _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumSet"] + ) + + case 5: + kwargs["foo_enum_map"] = _deserialize_foo_enum_map( + de, _SCHEMA_JSON_ENUMS_INPUT.members["fooEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_ENUMS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonEnumsOutput: + """Dataclass for JsonEnumsOutput structure.""" + + foo_enum1: str | None = None + + foo_enum2: str | None = None + + foo_enum3: str | None = None + + foo_enum_list: list[str] | None = None + + foo_enum_set: list[str] | None = None + + foo_enum_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_ENUMS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo_enum1 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum1"], self.foo_enum1 + ) + + if self.foo_enum2 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum2"], self.foo_enum2 + ) + + if self.foo_enum3 is not None: + serializer.write_string( + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum3"], self.foo_enum3 + ) + + if self.foo_enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumList"], + self.foo_enum_list, + ) + + if self.foo_enum_set is not None: + _serialize_foo_enum_set( + serializer, + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumSet"], + self.foo_enum_set, + ) + + if self.foo_enum_map is not None: + _serialize_foo_enum_map( + serializer, + _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumMap"], + self.foo_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo_enum1"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum1"]) + ) + + case 1: + kwargs["foo_enum2"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum2"]) + ) + + case 2: + kwargs["foo_enum3"] = FooEnum( + de.read_string(_SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnum3"]) + ) + + case 3: + kwargs["foo_enum_list"] = _deserialize_foo_enum_list( + de, _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumList"] + ) + + case 4: + kwargs["foo_enum_set"] = _deserialize_foo_enum_set( + de, _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumSet"] + ) + + case 5: + kwargs["foo_enum_map"] = _deserialize_foo_enum_map( + de, _SCHEMA_JSON_ENUMS_OUTPUT.members["fooEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_ENUMS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_ENUMS = APIOperation( + input=JsonEnumsInput, + output=JsonEnumsOutput, + schema=_SCHEMA_JSON_ENUMS, + input_schema=_SCHEMA_JSON_ENUMS_INPUT, + output_schema=_SCHEMA_JSON_ENUMS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_integer_enum_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, int] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_integer(value_schema, v)) + + +def _deserialize_integer_enum_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, int]: + result: dict[str, int] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = IntegerEnum(d.read_integer(value_schema)) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_integer_enum_set( + serializer: ShapeSerializer, schema: Schema, value: list[int] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_integer(member_schema, e) + + +def _deserialize_integer_enum_set( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int]: + result: list[int] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(IntegerEnum(d.read_integer(member_schema))) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class JsonIntEnumsInput: + """Dataclass for JsonIntEnumsInput structure.""" + + integer_enum1: int | None = None + + integer_enum2: int | None = None + + integer_enum3: int | None = None + + integer_enum_list: list[int] | None = None + + integer_enum_set: list[int] | None = None + + integer_enum_map: dict[str, int] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_INT_ENUMS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.integer_enum1 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnum1"], self.integer_enum1 + ) + + if self.integer_enum2 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnum2"], self.integer_enum2 + ) + + if self.integer_enum3 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnum3"], self.integer_enum3 + ) + + if self.integer_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnumList"], + self.integer_enum_list, + ) + + if self.integer_enum_set is not None: + _serialize_integer_enum_set( + serializer, + _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnumSet"], + self.integer_enum_set, + ) + + if self.integer_enum_map is not None: + _serialize_integer_enum_map( + serializer, + _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnumMap"], + self.integer_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["integer_enum1"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnum1"] + ) + ) + + case 1: + kwargs["integer_enum2"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnum2"] + ) + ) + + case 2: + kwargs["integer_enum3"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnum3"] + ) + ) + + case 3: + kwargs["integer_enum_list"] = _deserialize_integer_enum_list( + de, _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnumList"] + ) + + case 4: + kwargs["integer_enum_set"] = _deserialize_integer_enum_set( + de, _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnumSet"] + ) + + case 5: + kwargs["integer_enum_map"] = _deserialize_integer_enum_map( + de, _SCHEMA_JSON_INT_ENUMS_INPUT.members["integerEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_INT_ENUMS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonIntEnumsOutput: + """Dataclass for JsonIntEnumsOutput structure.""" + + integer_enum1: int | None = None + + integer_enum2: int | None = None + + integer_enum3: int | None = None + + integer_enum_list: list[int] | None = None + + integer_enum_set: list[int] | None = None + + integer_enum_map: dict[str, int] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_INT_ENUMS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.integer_enum1 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnum1"], + self.integer_enum1, + ) + + if self.integer_enum2 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnum2"], + self.integer_enum2, + ) + + if self.integer_enum3 is not None: + serializer.write_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnum3"], + self.integer_enum3, + ) + + if self.integer_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnumList"], + self.integer_enum_list, + ) + + if self.integer_enum_set is not None: + _serialize_integer_enum_set( + serializer, + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnumSet"], + self.integer_enum_set, + ) + + if self.integer_enum_map is not None: + _serialize_integer_enum_map( + serializer, + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnumMap"], + self.integer_enum_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["integer_enum1"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnum1"] + ) + ) + + case 1: + kwargs["integer_enum2"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnum2"] + ) + ) + + case 2: + kwargs["integer_enum3"] = IntegerEnum( + de.read_integer( + _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnum3"] + ) + ) + + case 3: + kwargs["integer_enum_list"] = _deserialize_integer_enum_list( + de, _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnumList"] + ) + + case 4: + kwargs["integer_enum_set"] = _deserialize_integer_enum_set( + de, _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnumSet"] + ) + + case 5: + kwargs["integer_enum_map"] = _deserialize_integer_enum_map( + de, _SCHEMA_JSON_INT_ENUMS_OUTPUT.members["integerEnumMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_INT_ENUMS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_INT_ENUMS = APIOperation( + input=JsonIntEnumsInput, + output=JsonIntEnumsOutput, + schema=_SCHEMA_JSON_INT_ENUMS, + input_schema=_SCHEMA_JSON_INT_ENUMS_INPUT, + output_schema=_SCHEMA_JSON_INT_ENUMS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_nested_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[list[str]] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + _serialize_string_list(ls, member_schema, e) + + +def _deserialize_nested_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[list[str]]: + result: list[list[str]] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(_deserialize_string_list(d, member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class StructureListMember: + """Dataclass for StructureListMember structure.""" + + a: str | None = None + + b: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STRUCTURE_LIST_MEMBER, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.a is not None: + serializer.write_string(_SCHEMA_STRUCTURE_LIST_MEMBER.members["a"], self.a) + + if self.b is not None: + serializer.write_string(_SCHEMA_STRUCTURE_LIST_MEMBER.members["b"], self.b) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["a"] = de.read_string( + _SCHEMA_STRUCTURE_LIST_MEMBER.members["a"] + ) + + case 1: + kwargs["b"] = de.read_string( + _SCHEMA_STRUCTURE_LIST_MEMBER.members["b"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_STRUCTURE_LIST_MEMBER, consumer=_consumer) + return kwargs + + +def _serialize_structure_list( + serializer: ShapeSerializer, schema: Schema, value: list[StructureListMember] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_struct(member_schema, e) + + +def _deserialize_structure_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[StructureListMember]: + result: list[StructureListMember] = [] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(StructureListMember.deserialize(d)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class JsonListsInput: + """Dataclass for JsonListsInput structure.""" + + string_list: list[str] | None = None + + string_set: list[str] | None = None + + integer_list: list[int] | None = None + + boolean_list: list[bool] | None = None + + timestamp_list: list[datetime] | None = None + + enum_list: list[str] | None = None + + int_enum_list: list[int] | None = None + + nested_string_list: list[list[str]] | None = None + """A list of lists of strings.""" + + structure_list: list[StructureListMember] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_LISTS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string_list is not None: + _serialize_string_list( + serializer, + _SCHEMA_JSON_LISTS_INPUT.members["stringList"], + self.string_list, + ) + + if self.string_set is not None: + _serialize_string_set( + serializer, + _SCHEMA_JSON_LISTS_INPUT.members["stringSet"], + self.string_set, + ) + + if self.integer_list is not None: + _serialize_integer_list( + serializer, + _SCHEMA_JSON_LISTS_INPUT.members["integerList"], + self.integer_list, + ) + + if self.boolean_list is not None: + _serialize_boolean_list( + serializer, + _SCHEMA_JSON_LISTS_INPUT.members["booleanList"], + self.boolean_list, + ) + + if self.timestamp_list is not None: + _serialize_timestamp_list( + serializer, + _SCHEMA_JSON_LISTS_INPUT.members["timestampList"], + self.timestamp_list, + ) + + if self.enum_list is not None: + _serialize_foo_enum_list( + serializer, _SCHEMA_JSON_LISTS_INPUT.members["enumList"], self.enum_list + ) + + if self.int_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_JSON_LISTS_INPUT.members["intEnumList"], + self.int_enum_list, + ) + + if self.nested_string_list is not None: + _serialize_nested_string_list( + serializer, + _SCHEMA_JSON_LISTS_INPUT.members["nestedStringList"], + self.nested_string_list, + ) + + if self.structure_list is not None: + _serialize_structure_list( + serializer, + _SCHEMA_JSON_LISTS_INPUT.members["structureList"], + self.structure_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string_list"] = _deserialize_string_list( + de, _SCHEMA_JSON_LISTS_INPUT.members["stringList"] + ) + + case 1: + kwargs["string_set"] = _deserialize_string_set( + de, _SCHEMA_JSON_LISTS_INPUT.members["stringSet"] + ) + + case 2: + kwargs["integer_list"] = _deserialize_integer_list( + de, _SCHEMA_JSON_LISTS_INPUT.members["integerList"] + ) + + case 3: + kwargs["boolean_list"] = _deserialize_boolean_list( + de, _SCHEMA_JSON_LISTS_INPUT.members["booleanList"] + ) + + case 4: + kwargs["timestamp_list"] = _deserialize_timestamp_list( + de, _SCHEMA_JSON_LISTS_INPUT.members["timestampList"] + ) + + case 5: + kwargs["enum_list"] = _deserialize_foo_enum_list( + de, _SCHEMA_JSON_LISTS_INPUT.members["enumList"] + ) + + case 6: + kwargs["int_enum_list"] = _deserialize_integer_enum_list( + de, _SCHEMA_JSON_LISTS_INPUT.members["intEnumList"] + ) + + case 7: + kwargs["nested_string_list"] = _deserialize_nested_string_list( + de, _SCHEMA_JSON_LISTS_INPUT.members["nestedStringList"] + ) + + case 8: + kwargs["structure_list"] = _deserialize_structure_list( + de, _SCHEMA_JSON_LISTS_INPUT.members["structureList"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_LISTS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonListsOutput: + """Dataclass for JsonListsOutput structure.""" + + string_list: list[str] | None = None + + string_set: list[str] | None = None + + integer_list: list[int] | None = None + + boolean_list: list[bool] | None = None + + timestamp_list: list[datetime] | None = None + + enum_list: list[str] | None = None + + int_enum_list: list[int] | None = None + + nested_string_list: list[list[str]] | None = None + """A list of lists of strings.""" + + structure_list: list[StructureListMember] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_LISTS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.string_list is not None: + _serialize_string_list( + serializer, + _SCHEMA_JSON_LISTS_OUTPUT.members["stringList"], + self.string_list, + ) + + if self.string_set is not None: + _serialize_string_set( + serializer, + _SCHEMA_JSON_LISTS_OUTPUT.members["stringSet"], + self.string_set, + ) + + if self.integer_list is not None: + _serialize_integer_list( + serializer, + _SCHEMA_JSON_LISTS_OUTPUT.members["integerList"], + self.integer_list, + ) + + if self.boolean_list is not None: + _serialize_boolean_list( + serializer, + _SCHEMA_JSON_LISTS_OUTPUT.members["booleanList"], + self.boolean_list, + ) + + if self.timestamp_list is not None: + _serialize_timestamp_list( + serializer, + _SCHEMA_JSON_LISTS_OUTPUT.members["timestampList"], + self.timestamp_list, + ) + + if self.enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_JSON_LISTS_OUTPUT.members["enumList"], + self.enum_list, + ) + + if self.int_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_JSON_LISTS_OUTPUT.members["intEnumList"], + self.int_enum_list, + ) + + if self.nested_string_list is not None: + _serialize_nested_string_list( + serializer, + _SCHEMA_JSON_LISTS_OUTPUT.members["nestedStringList"], + self.nested_string_list, + ) + + if self.structure_list is not None: + _serialize_structure_list( + serializer, + _SCHEMA_JSON_LISTS_OUTPUT.members["structureList"], + self.structure_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["string_list"] = _deserialize_string_list( + de, _SCHEMA_JSON_LISTS_OUTPUT.members["stringList"] + ) + + case 1: + kwargs["string_set"] = _deserialize_string_set( + de, _SCHEMA_JSON_LISTS_OUTPUT.members["stringSet"] + ) + + case 2: + kwargs["integer_list"] = _deserialize_integer_list( + de, _SCHEMA_JSON_LISTS_OUTPUT.members["integerList"] + ) + + case 3: + kwargs["boolean_list"] = _deserialize_boolean_list( + de, _SCHEMA_JSON_LISTS_OUTPUT.members["booleanList"] + ) + + case 4: + kwargs["timestamp_list"] = _deserialize_timestamp_list( + de, _SCHEMA_JSON_LISTS_OUTPUT.members["timestampList"] + ) + + case 5: + kwargs["enum_list"] = _deserialize_foo_enum_list( + de, _SCHEMA_JSON_LISTS_OUTPUT.members["enumList"] + ) + + case 6: + kwargs["int_enum_list"] = _deserialize_integer_enum_list( + de, _SCHEMA_JSON_LISTS_OUTPUT.members["intEnumList"] + ) + + case 7: + kwargs["nested_string_list"] = _deserialize_nested_string_list( + de, _SCHEMA_JSON_LISTS_OUTPUT.members["nestedStringList"] + ) + + case 8: + kwargs["structure_list"] = _deserialize_structure_list( + de, _SCHEMA_JSON_LISTS_OUTPUT.members["structureList"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_LISTS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_LISTS = APIOperation( + input=JsonListsInput, + output=JsonListsOutput, + schema=_SCHEMA_JSON_LISTS, + input_schema=_SCHEMA_JSON_LISTS_INPUT, + output_schema=_SCHEMA_JSON_LISTS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class JsonMapsInput: + """Dataclass for JsonMapsInput structure.""" + + dense_struct_map: dict[str, GreetingStruct] | None = None + + dense_number_map: dict[str, int] | None = None + + dense_boolean_map: dict[str, bool] | None = None + + dense_string_map: dict[str, str] | None = None + + dense_set_map: dict[str, list[str]] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_MAPS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.dense_struct_map is not None: + _serialize_dense_struct_map( + serializer, + _SCHEMA_JSON_MAPS_INPUT.members["denseStructMap"], + self.dense_struct_map, + ) + + if self.dense_number_map is not None: + _serialize_dense_number_map( + serializer, + _SCHEMA_JSON_MAPS_INPUT.members["denseNumberMap"], + self.dense_number_map, + ) + + if self.dense_boolean_map is not None: + _serialize_dense_boolean_map( + serializer, + _SCHEMA_JSON_MAPS_INPUT.members["denseBooleanMap"], + self.dense_boolean_map, + ) + + if self.dense_string_map is not None: + _serialize_dense_string_map( + serializer, + _SCHEMA_JSON_MAPS_INPUT.members["denseStringMap"], + self.dense_string_map, + ) + + if self.dense_set_map is not None: + _serialize_dense_set_map( + serializer, + _SCHEMA_JSON_MAPS_INPUT.members["denseSetMap"], + self.dense_set_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["dense_struct_map"] = _deserialize_dense_struct_map( + de, _SCHEMA_JSON_MAPS_INPUT.members["denseStructMap"] + ) + + case 1: + kwargs["dense_number_map"] = _deserialize_dense_number_map( + de, _SCHEMA_JSON_MAPS_INPUT.members["denseNumberMap"] + ) + + case 2: + kwargs["dense_boolean_map"] = _deserialize_dense_boolean_map( + de, _SCHEMA_JSON_MAPS_INPUT.members["denseBooleanMap"] + ) + + case 3: + kwargs["dense_string_map"] = _deserialize_dense_string_map( + de, _SCHEMA_JSON_MAPS_INPUT.members["denseStringMap"] + ) + + case 4: + kwargs["dense_set_map"] = _deserialize_dense_set_map( + de, _SCHEMA_JSON_MAPS_INPUT.members["denseSetMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_MAPS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonMapsOutput: + """Dataclass for JsonMapsOutput structure.""" + + dense_struct_map: dict[str, GreetingStruct] | None = None + + dense_number_map: dict[str, int] | None = None + + dense_boolean_map: dict[str, bool] | None = None + + dense_string_map: dict[str, str] | None = None + + dense_set_map: dict[str, list[str]] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_MAPS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.dense_struct_map is not None: + _serialize_dense_struct_map( + serializer, + _SCHEMA_JSON_MAPS_OUTPUT.members["denseStructMap"], + self.dense_struct_map, + ) + + if self.dense_number_map is not None: + _serialize_dense_number_map( + serializer, + _SCHEMA_JSON_MAPS_OUTPUT.members["denseNumberMap"], + self.dense_number_map, + ) + + if self.dense_boolean_map is not None: + _serialize_dense_boolean_map( + serializer, + _SCHEMA_JSON_MAPS_OUTPUT.members["denseBooleanMap"], + self.dense_boolean_map, + ) + + if self.dense_string_map is not None: + _serialize_dense_string_map( + serializer, + _SCHEMA_JSON_MAPS_OUTPUT.members["denseStringMap"], + self.dense_string_map, + ) + + if self.dense_set_map is not None: + _serialize_dense_set_map( + serializer, + _SCHEMA_JSON_MAPS_OUTPUT.members["denseSetMap"], + self.dense_set_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["dense_struct_map"] = _deserialize_dense_struct_map( + de, _SCHEMA_JSON_MAPS_OUTPUT.members["denseStructMap"] + ) + + case 1: + kwargs["dense_number_map"] = _deserialize_dense_number_map( + de, _SCHEMA_JSON_MAPS_OUTPUT.members["denseNumberMap"] + ) + + case 2: + kwargs["dense_boolean_map"] = _deserialize_dense_boolean_map( + de, _SCHEMA_JSON_MAPS_OUTPUT.members["denseBooleanMap"] + ) + + case 3: + kwargs["dense_string_map"] = _deserialize_dense_string_map( + de, _SCHEMA_JSON_MAPS_OUTPUT.members["denseStringMap"] + ) + + case 4: + kwargs["dense_set_map"] = _deserialize_dense_set_map( + de, _SCHEMA_JSON_MAPS_OUTPUT.members["denseSetMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_MAPS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_MAPS = APIOperation( + input=JsonMapsInput, + output=JsonMapsOutput, + schema=_SCHEMA_JSON_MAPS, + input_schema=_SCHEMA_JSON_MAPS_INPUT, + output_schema=_SCHEMA_JSON_MAPS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class JsonTimestampsInput: + """Dataclass for JsonTimestampsInput structure.""" + + normal: datetime | None = None + + date_time: datetime | None = None + + date_time_on_target: datetime | None = None + + epoch_seconds: datetime | None = None + + epoch_seconds_on_target: datetime | None = None + + http_date: datetime | None = None + + http_date_on_target: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_TIMESTAMPS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.normal is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["normal"], self.normal + ) + + if self.date_time is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["dateTime"], self.date_time + ) + + if self.date_time_on_target is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["dateTimeOnTarget"], + self.date_time_on_target, + ) + + if self.epoch_seconds is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["epochSeconds"], + self.epoch_seconds, + ) + + if self.epoch_seconds_on_target is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["epochSecondsOnTarget"], + self.epoch_seconds_on_target, + ) + + if self.http_date is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["httpDate"], self.http_date + ) + + if self.http_date_on_target is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["httpDateOnTarget"], + self.http_date_on_target, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["normal"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["normal"] + ) + + case 1: + kwargs["date_time"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["dateTime"] + ) + + case 2: + kwargs["date_time_on_target"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["dateTimeOnTarget"] + ) + + case 3: + kwargs["epoch_seconds"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["epochSeconds"] + ) + + case 4: + kwargs["epoch_seconds_on_target"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["epochSecondsOnTarget"] + ) + + case 5: + kwargs["http_date"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["httpDate"] + ) + + case 6: + kwargs["http_date_on_target"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_INPUT.members["httpDateOnTarget"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_TIMESTAMPS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonTimestampsOutput: + """Dataclass for JsonTimestampsOutput structure.""" + + normal: datetime | None = None + + date_time: datetime | None = None + + date_time_on_target: datetime | None = None + + epoch_seconds: datetime | None = None + + epoch_seconds_on_target: datetime | None = None + + http_date: datetime | None = None + + http_date_on_target: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_TIMESTAMPS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.normal is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["normal"], self.normal + ) + + if self.date_time is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["dateTime"], self.date_time + ) + + if self.date_time_on_target is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["dateTimeOnTarget"], + self.date_time_on_target, + ) + + if self.epoch_seconds is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["epochSeconds"], + self.epoch_seconds, + ) + + if self.epoch_seconds_on_target is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["epochSecondsOnTarget"], + self.epoch_seconds_on_target, + ) + + if self.http_date is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["httpDate"], self.http_date + ) + + if self.http_date_on_target is not None: + serializer.write_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["httpDateOnTarget"], + self.http_date_on_target, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["normal"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["normal"] + ) + + case 1: + kwargs["date_time"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["dateTime"] + ) + + case 2: + kwargs["date_time_on_target"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["dateTimeOnTarget"] + ) + + case 3: + kwargs["epoch_seconds"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["epochSeconds"] + ) + + case 4: + kwargs["epoch_seconds_on_target"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["epochSecondsOnTarget"] + ) + + case 5: + kwargs["http_date"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["httpDate"] + ) + + case 6: + kwargs["http_date_on_target"] = de.read_timestamp( + _SCHEMA_JSON_TIMESTAMPS_OUTPUT.members["httpDateOnTarget"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_TIMESTAMPS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_TIMESTAMPS = APIOperation( + input=JsonTimestampsInput, + output=JsonTimestampsOutput, + schema=_SCHEMA_JSON_TIMESTAMPS, + input_schema=_SCHEMA_JSON_TIMESTAMPS_INPUT, + output_schema=_SCHEMA_JSON_TIMESTAMPS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class RenamedGreeting: + """Dataclass for GreetingStruct structure.""" + + salutation: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RENAMED_GREETING, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.salutation is not None: + serializer.write_string( + _SCHEMA_RENAMED_GREETING.members["salutation"], self.salutation + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["salutation"] = de.read_string( + _SCHEMA_RENAMED_GREETING.members["salutation"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_RENAMED_GREETING, consumer=_consumer) + return kwargs + + +@dataclass +class NestedUnionStringValue: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NESTED_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_NESTED_UNION.members["stringValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_NESTED_UNION.members["stringValue"]) + ) + + +@dataclass +class NestedUnionUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +NestedUnion = Union[NestedUnionStringValue | NestedUnionUnknown] +"""A union used to test unions nested inside unions.""" + + +class _NestedUnionDeserializer: + _result: NestedUnion | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> NestedUnion: + self._result = None + deserializer.read_struct(_SCHEMA_NESTED_UNION, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(NestedUnionStringValue.deserialize(de)) + + case _: + self._set_result(NestedUnionUnknown(tag=schema.expect_member_name())) + + def _set_result(self, value: NestedUnion) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass +class MyUnionStringValue: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_MY_UNION.members["stringValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_MY_UNION.members["stringValue"]) + ) + + +@dataclass +class MyUnionBooleanValue: + value: bool + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_boolean(_SCHEMA_MY_UNION.members["booleanValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_boolean(_SCHEMA_MY_UNION.members["booleanValue"]) + ) + + +@dataclass +class MyUnionNumberValue: + value: int + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_integer(_SCHEMA_MY_UNION.members["numberValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_integer(_SCHEMA_MY_UNION.members["numberValue"]) + ) + + +@dataclass +class MyUnionBlobValue: + value: bytes + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_blob(_SCHEMA_MY_UNION.members["blobValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=deserializer.read_blob(_SCHEMA_MY_UNION.members["blobValue"])) + + +@dataclass +class MyUnionTimestampValue: + value: datetime + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_timestamp( + _SCHEMA_MY_UNION.members["timestampValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_timestamp( + _SCHEMA_MY_UNION.members["timestampValue"] + ) + ) + + +@dataclass +class MyUnionEnumValue: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_MY_UNION.members["enumValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=FooEnum( + deserializer.read_string(_SCHEMA_MY_UNION.members["enumValue"]) + ) + ) + + +@dataclass +class MyUnionListValue: + value: list[str] + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + _serialize_string_list( + serializer, _SCHEMA_MY_UNION.members["listValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=_deserialize_string_list( + deserializer, _SCHEMA_MY_UNION.members["listValue"] + ) + ) + + +@dataclass +class MyUnionMapValue: + value: dict[str, str] + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + _serialize_string_map( + serializer, _SCHEMA_MY_UNION.members["mapValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=_deserialize_string_map( + deserializer, _SCHEMA_MY_UNION.members["mapValue"] + ) + ) + + +@dataclass +class MyUnionStructureValue: + value: GreetingStruct + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION.members["structureValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=GreetingStruct.deserialize(deserializer)) + + +@dataclass +class MyUnionRenamedStructureValue: + value: RenamedGreeting + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MY_UNION.members["renamedStructureValue"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=RenamedGreeting.deserialize(deserializer)) + + +@dataclass +class MyUnionUnionValue: + """A union used to test unions nested inside unions.""" + + value: NestedUnion + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MY_UNION.members["unionValue"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=_NestedUnionDeserializer().deserialize(deserializer)) + + +@dataclass +class MyUnionUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +MyUnion = Union[ + MyUnionStringValue + | MyUnionBooleanValue + | MyUnionNumberValue + | MyUnionBlobValue + | MyUnionTimestampValue + | MyUnionEnumValue + | MyUnionListValue + | MyUnionMapValue + | MyUnionStructureValue + | MyUnionRenamedStructureValue + | MyUnionUnionValue + | MyUnionUnknown +] +"""A union with a representative set of types for members.""" + + +class _MyUnionDeserializer: + _result: MyUnion | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> MyUnion: + self._result = None + deserializer.read_struct(_SCHEMA_MY_UNION, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(MyUnionStringValue.deserialize(de)) + + case 1: + self._set_result(MyUnionBooleanValue.deserialize(de)) + + case 2: + self._set_result(MyUnionNumberValue.deserialize(de)) + + case 3: + self._set_result(MyUnionBlobValue.deserialize(de)) + + case 4: + self._set_result(MyUnionTimestampValue.deserialize(de)) + + case 5: + self._set_result(MyUnionEnumValue.deserialize(de)) + + case 6: + self._set_result(MyUnionListValue.deserialize(de)) + + case 7: + self._set_result(MyUnionMapValue.deserialize(de)) + + case 8: + self._set_result(MyUnionStructureValue.deserialize(de)) + + case 9: + self._set_result(MyUnionRenamedStructureValue.deserialize(de)) + + case 10: + self._set_result(MyUnionUnionValue.deserialize(de)) + + case _: + self._set_result(MyUnionUnknown(tag=schema.expect_member_name())) + + def _set_result(self, value: MyUnion) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class JsonUnionsInput: + """A shared structure that contains a single union member.""" + + contents: MyUnion | None = None + """A union with a representative set of types for members.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_UNIONS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.contents is not None: + serializer.write_struct( + _SCHEMA_JSON_UNIONS_INPUT.members["contents"], self.contents + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["contents"] = _MyUnionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_UNIONS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class JsonUnionsOutput: + """A shared structure that contains a single union member.""" + + contents: MyUnion | None = None + """A union with a representative set of types for members.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_JSON_UNIONS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.contents is not None: + serializer.write_struct( + _SCHEMA_JSON_UNIONS_OUTPUT.members["contents"], self.contents + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["contents"] = _MyUnionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_JSON_UNIONS_OUTPUT, consumer=_consumer) + return kwargs + + +JSON_UNIONS = APIOperation( + input=JsonUnionsInput, + output=JsonUnionsOutput, + schema=_SCHEMA_JSON_UNIONS, + input_schema=_SCHEMA_JSON_UNIONS_INPUT, + output_schema=_SCHEMA_JSON_UNIONS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedAcceptWithBodyInput: + """Dataclass for MalformedAcceptWithBodyInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_ACCEPT_WITH_BODY_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_ACCEPT_WITH_BODY_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedAcceptWithBodyOutput: + """Dataclass for MalformedAcceptWithBodyOutput structure.""" + + hi: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_ACCEPT_WITH_BODY_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.hi is not None: + serializer.write_string( + _SCHEMA_MALFORMED_ACCEPT_WITH_BODY_OUTPUT.members["hi"], self.hi + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["hi"] = de.read_string( + _SCHEMA_MALFORMED_ACCEPT_WITH_BODY_OUTPUT.members["hi"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_ACCEPT_WITH_BODY_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_ACCEPT_WITH_BODY = APIOperation( + input=MalformedAcceptWithBodyInput, + output=MalformedAcceptWithBodyOutput, + schema=_SCHEMA_MALFORMED_ACCEPT_WITH_BODY, + input_schema=_SCHEMA_MALFORMED_ACCEPT_WITH_BODY_INPUT, + output_schema=_SCHEMA_MALFORMED_ACCEPT_WITH_BODY_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedAcceptWithGenericStringInput: + """Dataclass for MalformedAcceptWithGenericStringInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_INPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedAcceptWithGenericStringOutput: + """Dataclass for MalformedAcceptWithGenericStringOutput structure.""" + + payload: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_string( + _SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_OUTPUT.members["payload"], + self.payload, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = de.read_string( + _SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_OUTPUT.members[ + "payload" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_ACCEPT_WITH_GENERIC_STRING = APIOperation( + input=MalformedAcceptWithGenericStringInput, + output=MalformedAcceptWithGenericStringOutput, + schema=_SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING, + input_schema=_SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_INPUT, + output_schema=_SCHEMA_MALFORMED_ACCEPT_WITH_GENERIC_STRING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedAcceptWithPayloadInput: + """Dataclass for MalformedAcceptWithPayloadInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedAcceptWithPayloadOutput: + """Dataclass for MalformedAcceptWithPayloadOutput structure.""" + + payload: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_blob( + _SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_OUTPUT.members["payload"], + self.payload, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = de.read_blob( + _SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_OUTPUT.members["payload"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_ACCEPT_WITH_PAYLOAD = APIOperation( + input=MalformedAcceptWithPayloadInput, + output=MalformedAcceptWithPayloadOutput, + schema=_SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD, + input_schema=_SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_INPUT, + output_schema=_SCHEMA_MALFORMED_ACCEPT_WITH_PAYLOAD_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedBlobInput: + """Dataclass for MalformedBlobInput structure.""" + + blob: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_BLOB_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.blob is not None: + serializer.write_blob( + _SCHEMA_MALFORMED_BLOB_INPUT.members["blob"], self.blob + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["blob"] = de.read_blob( + _SCHEMA_MALFORMED_BLOB_INPUT.members["blob"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_BLOB_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedBlobOutput: + """Dataclass for MalformedBlobOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_BLOB_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_BLOB_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_BLOB = APIOperation( + input=MalformedBlobInput, + output=MalformedBlobOutput, + schema=_SCHEMA_MALFORMED_BLOB, + input_schema=_SCHEMA_MALFORMED_BLOB_INPUT, + output_schema=_SCHEMA_MALFORMED_BLOB_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedBooleanInput: + """Dataclass for MalformedBooleanInput structure.""" + + boolean_in_body: bool | None = None + + boolean_in_path: bool | None = None + + boolean_in_query: bool | None = None + + boolean_in_header: bool | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_BOOLEAN_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.boolean_in_body is not None: + serializer.write_boolean( + _SCHEMA_MALFORMED_BOOLEAN_INPUT.members["booleanInBody"], + self.boolean_in_body, + ) + + if self.boolean_in_path is not None: + serializer.write_boolean( + _SCHEMA_MALFORMED_BOOLEAN_INPUT.members["booleanInPath"], + self.boolean_in_path, + ) + + if self.boolean_in_query is not None: + serializer.write_boolean( + _SCHEMA_MALFORMED_BOOLEAN_INPUT.members["booleanInQuery"], + self.boolean_in_query, + ) + + if self.boolean_in_header is not None: + serializer.write_boolean( + _SCHEMA_MALFORMED_BOOLEAN_INPUT.members["booleanInHeader"], + self.boolean_in_header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["boolean_in_body"] = de.read_boolean( + _SCHEMA_MALFORMED_BOOLEAN_INPUT.members["booleanInBody"] + ) + + case 1: + kwargs["boolean_in_path"] = de.read_boolean( + _SCHEMA_MALFORMED_BOOLEAN_INPUT.members["booleanInPath"] + ) + + case 2: + kwargs["boolean_in_query"] = de.read_boolean( + _SCHEMA_MALFORMED_BOOLEAN_INPUT.members["booleanInQuery"] + ) + + case 3: + kwargs["boolean_in_header"] = de.read_boolean( + _SCHEMA_MALFORMED_BOOLEAN_INPUT.members["booleanInHeader"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_BOOLEAN_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedBooleanOutput: + """Dataclass for MalformedBooleanOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_BOOLEAN_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_BOOLEAN_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_BOOLEAN = APIOperation( + input=MalformedBooleanInput, + output=MalformedBooleanOutput, + schema=_SCHEMA_MALFORMED_BOOLEAN, + input_schema=_SCHEMA_MALFORMED_BOOLEAN_INPUT, + output_schema=_SCHEMA_MALFORMED_BOOLEAN_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedByteInput: + """Dataclass for MalformedByteInput structure.""" + + byte_in_body: int | None = None + + byte_in_path: int | None = None + + byte_in_query: int | None = None + + byte_in_header: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_BYTE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.byte_in_body is not None: + serializer.write_byte( + _SCHEMA_MALFORMED_BYTE_INPUT.members["byteInBody"], self.byte_in_body + ) + + if self.byte_in_path is not None: + serializer.write_byte( + _SCHEMA_MALFORMED_BYTE_INPUT.members["byteInPath"], self.byte_in_path + ) + + if self.byte_in_query is not None: + serializer.write_byte( + _SCHEMA_MALFORMED_BYTE_INPUT.members["byteInQuery"], self.byte_in_query + ) + + if self.byte_in_header is not None: + serializer.write_byte( + _SCHEMA_MALFORMED_BYTE_INPUT.members["byteInHeader"], + self.byte_in_header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["byte_in_body"] = de.read_byte( + _SCHEMA_MALFORMED_BYTE_INPUT.members["byteInBody"] + ) + + case 1: + kwargs["byte_in_path"] = de.read_byte( + _SCHEMA_MALFORMED_BYTE_INPUT.members["byteInPath"] + ) + + case 2: + kwargs["byte_in_query"] = de.read_byte( + _SCHEMA_MALFORMED_BYTE_INPUT.members["byteInQuery"] + ) + + case 3: + kwargs["byte_in_header"] = de.read_byte( + _SCHEMA_MALFORMED_BYTE_INPUT.members["byteInHeader"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_BYTE_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedByteOutput: + """Dataclass for MalformedByteOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_BYTE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_BYTE_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_BYTE = APIOperation( + input=MalformedByteInput, + output=MalformedByteOutput, + schema=_SCHEMA_MALFORMED_BYTE, + input_schema=_SCHEMA_MALFORMED_BYTE_INPUT, + output_schema=_SCHEMA_MALFORMED_BYTE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedContentTypeWithBodyInput: + """Dataclass for MalformedContentTypeWithBodyInput structure.""" + + hi: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.hi is not None: + serializer.write_string( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_INPUT.members["hi"], self.hi + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["hi"] = de.read_string( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_INPUT.members["hi"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedContentTypeWithBodyOutput: + """Dataclass for MalformedContentTypeWithBodyOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_CONTENT_TYPE_WITH_BODY = APIOperation( + input=MalformedContentTypeWithBodyInput, + output=MalformedContentTypeWithBodyOutput, + schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY, + input_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_INPUT, + output_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_BODY_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedContentTypeWithGenericStringInput: + """Dataclass for MalformedContentTypeWithGenericStringInput structure.""" + + payload: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_INPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_string( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_INPUT.members[ + "payload" + ], + self.payload, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = de.read_string( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_INPUT.members[ + "payload" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedContentTypeWithGenericStringOutput: + """Dataclass for MalformedContentTypeWithGenericStringOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_OUTPUT, + consumer=_consumer, + ) + return kwargs + + +MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING = APIOperation( + input=MalformedContentTypeWithGenericStringInput, + output=MalformedContentTypeWithGenericStringOutput, + schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING, + input_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_INPUT, + output_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_GENERIC_STRING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedContentTypeWithoutBodyInput: + """Dataclass for MalformedContentTypeWithoutBodyInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedContentTypeWithoutBodyOutput: + """Dataclass for MalformedContentTypeWithoutBodyOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_CONTENT_TYPE_WITHOUT_BODY = APIOperation( + input=MalformedContentTypeWithoutBodyInput, + output=MalformedContentTypeWithoutBodyOutput, + schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY, + input_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_INPUT, + output_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedContentTypeWithoutBodyEmptyInputInput: + """Dataclass for MalformedContentTypeWithoutBodyEmptyInputInput structure.""" + + header: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_INPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.header is not None: + serializer.write_string( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_INPUT.members[ + "header" + ], + self.header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["header"] = de.read_string( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_INPUT.members[ + "header" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_INPUT, + consumer=_consumer, + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedContentTypeWithoutBodyEmptyInputOutput: + """Dataclass for MalformedContentTypeWithoutBodyEmptyInputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_OUTPUT, + consumer=_consumer, + ) + return kwargs + + +MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT = APIOperation( + input=MalformedContentTypeWithoutBodyEmptyInputInput, + output=MalformedContentTypeWithoutBodyEmptyInputOutput, + schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT, + input_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_INPUT, + output_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITHOUT_BODY_EMPTY_INPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedContentTypeWithPayloadInput: + """Dataclass for MalformedContentTypeWithPayloadInput structure.""" + + payload: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.payload is not None: + serializer.write_blob( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_INPUT.members["payload"], + self.payload, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["payload"] = de.read_blob( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_INPUT.members[ + "payload" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedContentTypeWithPayloadOutput: + """Dataclass for MalformedContentTypeWithPayloadOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_CONTENT_TYPE_WITH_PAYLOAD = APIOperation( + input=MalformedContentTypeWithPayloadInput, + output=MalformedContentTypeWithPayloadOutput, + schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD, + input_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_INPUT, + output_schema=_SCHEMA_MALFORMED_CONTENT_TYPE_WITH_PAYLOAD_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedDoubleInput: + """Dataclass for MalformedDoubleInput structure.""" + + double_in_body: float | None = None + + double_in_path: float | None = None + + double_in_query: float | None = None + + double_in_header: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_DOUBLE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.double_in_body is not None: + serializer.write_double( + _SCHEMA_MALFORMED_DOUBLE_INPUT.members["doubleInBody"], + self.double_in_body, + ) + + if self.double_in_path is not None: + serializer.write_double( + _SCHEMA_MALFORMED_DOUBLE_INPUT.members["doubleInPath"], + self.double_in_path, + ) + + if self.double_in_query is not None: + serializer.write_double( + _SCHEMA_MALFORMED_DOUBLE_INPUT.members["doubleInQuery"], + self.double_in_query, + ) + + if self.double_in_header is not None: + serializer.write_double( + _SCHEMA_MALFORMED_DOUBLE_INPUT.members["doubleInHeader"], + self.double_in_header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["double_in_body"] = de.read_double( + _SCHEMA_MALFORMED_DOUBLE_INPUT.members["doubleInBody"] + ) + + case 1: + kwargs["double_in_path"] = de.read_double( + _SCHEMA_MALFORMED_DOUBLE_INPUT.members["doubleInPath"] + ) + + case 2: + kwargs["double_in_query"] = de.read_double( + _SCHEMA_MALFORMED_DOUBLE_INPUT.members["doubleInQuery"] + ) + + case 3: + kwargs["double_in_header"] = de.read_double( + _SCHEMA_MALFORMED_DOUBLE_INPUT.members["doubleInHeader"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_DOUBLE_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedDoubleOutput: + """Dataclass for MalformedDoubleOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_DOUBLE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_DOUBLE_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_DOUBLE = APIOperation( + input=MalformedDoubleInput, + output=MalformedDoubleOutput, + schema=_SCHEMA_MALFORMED_DOUBLE, + input_schema=_SCHEMA_MALFORMED_DOUBLE_INPUT, + output_schema=_SCHEMA_MALFORMED_DOUBLE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedFloatInput: + """Dataclass for MalformedFloatInput structure.""" + + float_in_body: float | None = None + + float_in_path: float | None = None + + float_in_query: float | None = None + + float_in_header: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_FLOAT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.float_in_body is not None: + serializer.write_float( + _SCHEMA_MALFORMED_FLOAT_INPUT.members["floatInBody"], self.float_in_body + ) + + if self.float_in_path is not None: + serializer.write_float( + _SCHEMA_MALFORMED_FLOAT_INPUT.members["floatInPath"], self.float_in_path + ) + + if self.float_in_query is not None: + serializer.write_float( + _SCHEMA_MALFORMED_FLOAT_INPUT.members["floatInQuery"], + self.float_in_query, + ) + + if self.float_in_header is not None: + serializer.write_float( + _SCHEMA_MALFORMED_FLOAT_INPUT.members["floatInHeader"], + self.float_in_header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["float_in_body"] = de.read_float( + _SCHEMA_MALFORMED_FLOAT_INPUT.members["floatInBody"] + ) + + case 1: + kwargs["float_in_path"] = de.read_float( + _SCHEMA_MALFORMED_FLOAT_INPUT.members["floatInPath"] + ) + + case 2: + kwargs["float_in_query"] = de.read_float( + _SCHEMA_MALFORMED_FLOAT_INPUT.members["floatInQuery"] + ) + + case 3: + kwargs["float_in_header"] = de.read_float( + _SCHEMA_MALFORMED_FLOAT_INPUT.members["floatInHeader"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_FLOAT_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedFloatOutput: + """Dataclass for MalformedFloatOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_FLOAT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_FLOAT_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_FLOAT = APIOperation( + input=MalformedFloatInput, + output=MalformedFloatOutput, + schema=_SCHEMA_MALFORMED_FLOAT, + input_schema=_SCHEMA_MALFORMED_FLOAT_INPUT, + output_schema=_SCHEMA_MALFORMED_FLOAT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedIntegerInput: + """Dataclass for MalformedIntegerInput structure.""" + + integer_in_body: int | None = None + + integer_in_path: int | None = None + + integer_in_query: int | None = None + + integer_in_header: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_INTEGER_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.integer_in_body is not None: + serializer.write_integer( + _SCHEMA_MALFORMED_INTEGER_INPUT.members["integerInBody"], + self.integer_in_body, + ) + + if self.integer_in_path is not None: + serializer.write_integer( + _SCHEMA_MALFORMED_INTEGER_INPUT.members["integerInPath"], + self.integer_in_path, + ) + + if self.integer_in_query is not None: + serializer.write_integer( + _SCHEMA_MALFORMED_INTEGER_INPUT.members["integerInQuery"], + self.integer_in_query, + ) + + if self.integer_in_header is not None: + serializer.write_integer( + _SCHEMA_MALFORMED_INTEGER_INPUT.members["integerInHeader"], + self.integer_in_header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["integer_in_body"] = de.read_integer( + _SCHEMA_MALFORMED_INTEGER_INPUT.members["integerInBody"] + ) + + case 1: + kwargs["integer_in_path"] = de.read_integer( + _SCHEMA_MALFORMED_INTEGER_INPUT.members["integerInPath"] + ) + + case 2: + kwargs["integer_in_query"] = de.read_integer( + _SCHEMA_MALFORMED_INTEGER_INPUT.members["integerInQuery"] + ) + + case 3: + kwargs["integer_in_header"] = de.read_integer( + _SCHEMA_MALFORMED_INTEGER_INPUT.members["integerInHeader"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_INTEGER_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedIntegerOutput: + """Dataclass for MalformedIntegerOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_INTEGER_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_INTEGER_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_INTEGER = APIOperation( + input=MalformedIntegerInput, + output=MalformedIntegerOutput, + schema=_SCHEMA_MALFORMED_INTEGER, + input_schema=_SCHEMA_MALFORMED_INTEGER_INPUT, + output_schema=_SCHEMA_MALFORMED_INTEGER_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_simple_list( + serializer: ShapeSerializer, schema: Schema, value: list[str] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + ls.write_string(member_schema, e) + + +def _deserialize_simple_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str]: + result: list[str] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class MalformedListInput: + """Dataclass for MalformedListInput structure.""" + + body_list: list[str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_LIST_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.body_list is not None: + _serialize_simple_list( + serializer, + _SCHEMA_MALFORMED_LIST_INPUT.members["bodyList"], + self.body_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["body_list"] = _deserialize_simple_list( + de, _SCHEMA_MALFORMED_LIST_INPUT.members["bodyList"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_LIST_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedListOutput: + """Dataclass for MalformedListOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_LIST_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_LIST_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_LIST = APIOperation( + input=MalformedListInput, + output=MalformedListOutput, + schema=_SCHEMA_MALFORMED_LIST, + input_schema=_SCHEMA_MALFORMED_LIST_INPUT, + output_schema=_SCHEMA_MALFORMED_LIST_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedLongInput: + """Dataclass for MalformedLongInput structure.""" + + long_in_body: int | None = None + + long_in_path: int | None = None + + long_in_query: int | None = None + + long_in_header: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_LONG_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.long_in_body is not None: + serializer.write_long( + _SCHEMA_MALFORMED_LONG_INPUT.members["longInBody"], self.long_in_body + ) + + if self.long_in_path is not None: + serializer.write_long( + _SCHEMA_MALFORMED_LONG_INPUT.members["longInPath"], self.long_in_path + ) + + if self.long_in_query is not None: + serializer.write_long( + _SCHEMA_MALFORMED_LONG_INPUT.members["longInQuery"], self.long_in_query + ) + + if self.long_in_header is not None: + serializer.write_long( + _SCHEMA_MALFORMED_LONG_INPUT.members["longInHeader"], + self.long_in_header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["long_in_body"] = de.read_long( + _SCHEMA_MALFORMED_LONG_INPUT.members["longInBody"] + ) + + case 1: + kwargs["long_in_path"] = de.read_long( + _SCHEMA_MALFORMED_LONG_INPUT.members["longInPath"] + ) + + case 2: + kwargs["long_in_query"] = de.read_long( + _SCHEMA_MALFORMED_LONG_INPUT.members["longInQuery"] + ) + + case 3: + kwargs["long_in_header"] = de.read_long( + _SCHEMA_MALFORMED_LONG_INPUT.members["longInHeader"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_LONG_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedLongOutput: + """Dataclass for MalformedLongOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_LONG_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_LONG_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_LONG = APIOperation( + input=MalformedLongInput, + output=MalformedLongOutput, + schema=_SCHEMA_MALFORMED_LONG, + input_schema=_SCHEMA_MALFORMED_LONG_INPUT, + output_schema=_SCHEMA_MALFORMED_LONG_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_simple_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + m.entry(k, lambda vs: vs.write_string(value_schema, v)) + + +def _deserialize_simple_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str]: + result: dict[str, str] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class MalformedMapInput: + """Dataclass for MalformedMapInput structure.""" + + body_map: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_MAP_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.body_map is not None: + _serialize_simple_map( + serializer, + _SCHEMA_MALFORMED_MAP_INPUT.members["bodyMap"], + self.body_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["body_map"] = _deserialize_simple_map( + de, _SCHEMA_MALFORMED_MAP_INPUT.members["bodyMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_MAP_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedMapOutput: + """Dataclass for MalformedMapOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_MAP_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_MAP_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_MAP = APIOperation( + input=MalformedMapInput, + output=MalformedMapOutput, + schema=_SCHEMA_MALFORMED_MAP, + input_schema=_SCHEMA_MALFORMED_MAP_INPUT, + output_schema=_SCHEMA_MALFORMED_MAP_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedRequestBodyInput: + """Dataclass for MalformedRequestBodyInput structure.""" + + int_: int | None = None + + float_: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_REQUEST_BODY_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.int_ is not None: + serializer.write_integer( + _SCHEMA_MALFORMED_REQUEST_BODY_INPUT.members["int"], self.int_ + ) + + if self.float_ is not None: + serializer.write_float( + _SCHEMA_MALFORMED_REQUEST_BODY_INPUT.members["float"], self.float_ + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["int_"] = de.read_integer( + _SCHEMA_MALFORMED_REQUEST_BODY_INPUT.members["int"] + ) + + case 1: + kwargs["float_"] = de.read_float( + _SCHEMA_MALFORMED_REQUEST_BODY_INPUT.members["float"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_REQUEST_BODY_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedRequestBodyOutput: + """Dataclass for MalformedRequestBodyOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_REQUEST_BODY_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_REQUEST_BODY_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_REQUEST_BODY = APIOperation( + input=MalformedRequestBodyInput, + output=MalformedRequestBodyOutput, + schema=_SCHEMA_MALFORMED_REQUEST_BODY, + input_schema=_SCHEMA_MALFORMED_REQUEST_BODY_INPUT, + output_schema=_SCHEMA_MALFORMED_REQUEST_BODY_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedShortInput: + """Dataclass for MalformedShortInput structure.""" + + short_in_body: int | None = None + + short_in_path: int | None = None + + short_in_query: int | None = None + + short_in_header: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_SHORT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.short_in_body is not None: + serializer.write_short( + _SCHEMA_MALFORMED_SHORT_INPUT.members["shortInBody"], self.short_in_body + ) + + if self.short_in_path is not None: + serializer.write_short( + _SCHEMA_MALFORMED_SHORT_INPUT.members["shortInPath"], self.short_in_path + ) + + if self.short_in_query is not None: + serializer.write_short( + _SCHEMA_MALFORMED_SHORT_INPUT.members["shortInQuery"], + self.short_in_query, + ) + + if self.short_in_header is not None: + serializer.write_short( + _SCHEMA_MALFORMED_SHORT_INPUT.members["shortInHeader"], + self.short_in_header, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["short_in_body"] = de.read_short( + _SCHEMA_MALFORMED_SHORT_INPUT.members["shortInBody"] + ) + + case 1: + kwargs["short_in_path"] = de.read_short( + _SCHEMA_MALFORMED_SHORT_INPUT.members["shortInPath"] + ) + + case 2: + kwargs["short_in_query"] = de.read_short( + _SCHEMA_MALFORMED_SHORT_INPUT.members["shortInQuery"] + ) + + case 3: + kwargs["short_in_header"] = de.read_short( + _SCHEMA_MALFORMED_SHORT_INPUT.members["shortInHeader"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_SHORT_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedShortOutput: + """Dataclass for MalformedShortOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_SHORT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_SHORT_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_SHORT = APIOperation( + input=MalformedShortInput, + output=MalformedShortOutput, + schema=_SCHEMA_MALFORMED_SHORT, + input_schema=_SCHEMA_MALFORMED_SHORT_INPUT, + output_schema=_SCHEMA_MALFORMED_SHORT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedStringInput: + """Dataclass for MalformedStringInput structure.""" + + blob: str | JsonString | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_STRING_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.blob is not None: + serializer.write_string( + _SCHEMA_MALFORMED_STRING_INPUT.members["blob"], self.blob + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["blob"] = de.read_string( + _SCHEMA_MALFORMED_STRING_INPUT.members["blob"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_STRING_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedStringOutput: + """Dataclass for MalformedStringOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_STRING_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_STRING_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_STRING = APIOperation( + input=MalformedStringInput, + output=MalformedStringOutput, + schema=_SCHEMA_MALFORMED_STRING, + input_schema=_SCHEMA_MALFORMED_STRING_INPUT, + output_schema=_SCHEMA_MALFORMED_STRING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampBodyDateTimeInput: + """Dataclass for MalformedTimestampBodyDateTimeInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampBodyDateTimeOutput: + """Dataclass for MalformedTimestampBodyDateTimeOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_BODY_DATE_TIME = APIOperation( + input=MalformedTimestampBodyDateTimeInput, + output=MalformedTimestampBodyDateTimeOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_BODY_DATE_TIME_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampBodyDefaultInput: + """Dataclass for MalformedTimestampBodyDefaultInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampBodyDefaultOutput: + """Dataclass for MalformedTimestampBodyDefaultOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_BODY_DEFAULT = APIOperation( + input=MalformedTimestampBodyDefaultInput, + output=MalformedTimestampBodyDefaultOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_BODY_DEFAULT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampBodyHttpDateInput: + """Dataclass for MalformedTimestampBodyHttpDateInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampBodyHttpDateOutput: + """Dataclass for MalformedTimestampBodyHttpDateOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_BODY_HTTP_DATE = APIOperation( + input=MalformedTimestampBodyHttpDateInput, + output=MalformedTimestampBodyHttpDateOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_BODY_HTTP_DATE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampHeaderDateTimeInput: + """Dataclass for MalformedTimestampHeaderDateTimeInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_INPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampHeaderDateTimeOutput: + """Dataclass for MalformedTimestampHeaderDateTimeOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_HEADER_DATE_TIME = APIOperation( + input=MalformedTimestampHeaderDateTimeInput, + output=MalformedTimestampHeaderDateTimeOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_HEADER_DATE_TIME_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampHeaderDefaultInput: + """Dataclass for MalformedTimestampHeaderDefaultInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampHeaderDefaultOutput: + """Dataclass for MalformedTimestampHeaderDefaultOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_HEADER_DEFAULT = APIOperation( + input=MalformedTimestampHeaderDefaultInput, + output=MalformedTimestampHeaderDefaultOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_HEADER_DEFAULT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampHeaderEpochInput: + """Dataclass for MalformedTimestampHeaderEpochInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampHeaderEpochOutput: + """Dataclass for MalformedTimestampHeaderEpochOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_HEADER_EPOCH = APIOperation( + input=MalformedTimestampHeaderEpochInput, + output=MalformedTimestampHeaderEpochOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_HEADER_EPOCH_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampPathDefaultInput: + """Dataclass for MalformedTimestampPathDefaultInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampPathDefaultOutput: + """Dataclass for MalformedTimestampPathDefaultOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_PATH_DEFAULT = APIOperation( + input=MalformedTimestampPathDefaultInput, + output=MalformedTimestampPathDefaultOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_PATH_DEFAULT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampPathEpochInput: + """Dataclass for MalformedTimestampPathEpochInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampPathEpochOutput: + """Dataclass for MalformedTimestampPathEpochOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_PATH_EPOCH = APIOperation( + input=MalformedTimestampPathEpochInput, + output=MalformedTimestampPathEpochOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_PATH_EPOCH_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampPathHttpDateInput: + """Dataclass for MalformedTimestampPathHttpDateInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampPathHttpDateOutput: + """Dataclass for MalformedTimestampPathHttpDateOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_PATH_HTTP_DATE = APIOperation( + input=MalformedTimestampPathHttpDateInput, + output=MalformedTimestampPathHttpDateOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_PATH_HTTP_DATE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampQueryDefaultInput: + """Dataclass for MalformedTimestampQueryDefaultInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampQueryDefaultOutput: + """Dataclass for MalformedTimestampQueryDefaultOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_QUERY_DEFAULT = APIOperation( + input=MalformedTimestampQueryDefaultInput, + output=MalformedTimestampQueryDefaultOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_QUERY_DEFAULT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampQueryEpochInput: + """Dataclass for MalformedTimestampQueryEpochInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampQueryEpochOutput: + """Dataclass for MalformedTimestampQueryEpochOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_QUERY_EPOCH = APIOperation( + input=MalformedTimestampQueryEpochInput, + output=MalformedTimestampQueryEpochOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_QUERY_EPOCH_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MalformedTimestampQueryHttpDateInput: + """Dataclass for MalformedTimestampQueryHttpDateInput structure.""" + + timestamp: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timestamp is not None: + serializer.write_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_INPUT.members["timestamp"], + self.timestamp, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timestamp"] = de.read_timestamp( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_INPUT.members[ + "timestamp" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class MalformedTimestampQueryHttpDateOutput: + """Dataclass for MalformedTimestampQueryHttpDateOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_OUTPUT, consumer=_consumer + ) + return kwargs + + +MALFORMED_TIMESTAMP_QUERY_HTTP_DATE = APIOperation( + input=MalformedTimestampQueryHttpDateInput, + output=MalformedTimestampQueryHttpDateOutput, + schema=_SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE, + input_schema=_SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_INPUT, + output_schema=_SCHEMA_MALFORMED_TIMESTAMP_QUERY_HTTP_DATE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass +class SimpleUnionInt: + value: int + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_integer(_SCHEMA_SIMPLE_UNION.members["int"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=deserializer.read_integer(_SCHEMA_SIMPLE_UNION.members["int"])) + + +@dataclass +class SimpleUnionString: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_UNION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_SIMPLE_UNION.members["string"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_SIMPLE_UNION.members["string"]) + ) + + +@dataclass +class SimpleUnionUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +SimpleUnion = Union[SimpleUnionInt | SimpleUnionString | SimpleUnionUnknown] + + +class _SimpleUnionDeserializer: + _result: SimpleUnion | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> SimpleUnion: + self._result = None + deserializer.read_struct(_SCHEMA_SIMPLE_UNION, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(SimpleUnionInt.deserialize(de)) + + case 1: + self._set_result(SimpleUnionString.deserialize(de)) + + case _: + self._set_result(SimpleUnionUnknown(tag=schema.expect_member_name())) + + def _set_result(self, value: SimpleUnion) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class MalformedUnionInput: + """Dataclass for MalformedUnionInput structure.""" + + union: SimpleUnion | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_UNION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.union is not None: + serializer.write_struct( + _SCHEMA_MALFORMED_UNION_INPUT.members["union"], self.union + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["union"] = _SimpleUnionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_UNION_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MalformedUnionOutput: + """Dataclass for MalformedUnionOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MALFORMED_UNION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MALFORMED_UNION_OUTPUT, consumer=_consumer) + return kwargs + + +MALFORMED_UNION = APIOperation( + input=MalformedUnionInput, + output=MalformedUnionOutput, + schema=_SCHEMA_MALFORMED_UNION, + input_schema=_SCHEMA_MALFORMED_UNION_INPUT, + output_schema=_SCHEMA_MALFORMED_UNION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class MediaTypeHeaderInput: + """Dataclass for MediaTypeHeaderInput structure.""" + + json: str | JsonString | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MEDIA_TYPE_HEADER_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.json is not None: + serializer.write_string( + _SCHEMA_MEDIA_TYPE_HEADER_INPUT.members["json"], self.json + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["json"] = de.read_string( + _SCHEMA_MEDIA_TYPE_HEADER_INPUT.members["json"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MEDIA_TYPE_HEADER_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class MediaTypeHeaderOutput: + """Dataclass for MediaTypeHeaderOutput structure.""" + + json: str | JsonString | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_MEDIA_TYPE_HEADER_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.json is not None: + serializer.write_string( + _SCHEMA_MEDIA_TYPE_HEADER_OUTPUT.members["json"], self.json + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["json"] = de.read_string( + _SCHEMA_MEDIA_TYPE_HEADER_OUTPUT.members["json"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_MEDIA_TYPE_HEADER_OUTPUT, consumer=_consumer) + return kwargs + + +MEDIA_TYPE_HEADER = APIOperation( + input=MediaTypeHeaderInput, + output=MediaTypeHeaderOutput, + schema=_SCHEMA_MEDIA_TYPE_HEADER, + input_schema=_SCHEMA_MEDIA_TYPE_HEADER_INPUT, + output_schema=_SCHEMA_MEDIA_TYPE_HEADER_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NoInputAndNoOutputInput: + """Dataclass for NoInputAndNoOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class NoInputAndNoOutputOutput: + """Dataclass for NoInputAndNoOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, consumer=_consumer + ) + return kwargs + + +NO_INPUT_AND_NO_OUTPUT = APIOperation( + input=NoInputAndNoOutputInput, + output=NoInputAndNoOutputOutput, + schema=_SCHEMA_NO_INPUT_AND_NO_OUTPUT, + input_schema=_SCHEMA_NO_INPUT_AND_NO_OUTPUT_INPUT, + output_schema=_SCHEMA_NO_INPUT_AND_NO_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NoInputAndOutputInput: + """Dataclass for NoInputAndOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class NoInputAndOutputOutput: + """Dataclass for NoInputAndOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, consumer=_consumer) + return kwargs + + +NO_INPUT_AND_OUTPUT = APIOperation( + input=NoInputAndOutputInput, + output=NoInputAndOutputOutput, + schema=_SCHEMA_NO_INPUT_AND_OUTPUT, + input_schema=_SCHEMA_NO_INPUT_AND_OUTPUT_INPUT, + output_schema=_SCHEMA_NO_INPUT_AND_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NullAndEmptyHeadersClientInput: + """Dataclass for NullAndEmptyHeadersClientInput structure.""" + + a: str | None = None + + b: str | None = None + + c: list[str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.a is not None: + serializer.write_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT.members["a"], self.a + ) + + if self.b is not None: + serializer.write_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT.members["b"], self.b + ) + + if self.c is not None: + _serialize_string_list( + serializer, + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT.members["c"], + self.c, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["a"] = de.read_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT.members["a"] + ) + + case 1: + kwargs["b"] = de.read_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT.members["b"] + ) + + case 2: + kwargs["c"] = _deserialize_string_list( + de, _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT.members["c"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class NullAndEmptyHeadersClientOutput: + """Dataclass for NullAndEmptyHeadersClientOutput structure.""" + + a: str | None = None + + b: str | None = None + + c: list[str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.a is not None: + serializer.write_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT.members["a"], self.a + ) + + if self.b is not None: + serializer.write_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT.members["b"], self.b + ) + + if self.c is not None: + _serialize_string_list( + serializer, + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT.members["c"], + self.c, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["a"] = de.read_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT.members["a"] + ) + + case 1: + kwargs["b"] = de.read_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT.members["b"] + ) + + case 2: + kwargs["c"] = _deserialize_string_list( + de, _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT.members["c"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT, consumer=_consumer + ) + return kwargs + + +NULL_AND_EMPTY_HEADERS_CLIENT = APIOperation( + input=NullAndEmptyHeadersClientInput, + output=NullAndEmptyHeadersClientOutput, + schema=_SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT, + input_schema=_SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_INPUT, + output_schema=_SCHEMA_NULL_AND_EMPTY_HEADERS_CLIENT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class NullAndEmptyHeadersServerInput: + """Dataclass for NullAndEmptyHeadersServerInput structure.""" + + a: str | None = None + + b: str | None = None + + c: list[str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.a is not None: + serializer.write_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT.members["a"], self.a + ) + + if self.b is not None: + serializer.write_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT.members["b"], self.b + ) + + if self.c is not None: + _serialize_string_list( + serializer, + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT.members["c"], + self.c, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["a"] = de.read_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT.members["a"] + ) + + case 1: + kwargs["b"] = de.read_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT.members["b"] + ) + + case 2: + kwargs["c"] = _deserialize_string_list( + de, _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT.members["c"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class NullAndEmptyHeadersServerOutput: + """Dataclass for NullAndEmptyHeadersServerOutput structure.""" + + a: str | None = None + + b: str | None = None + + c: list[str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.a is not None: + serializer.write_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT.members["a"], self.a + ) + + if self.b is not None: + serializer.write_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT.members["b"], self.b + ) + + if self.c is not None: + _serialize_string_list( + serializer, + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT.members["c"], + self.c, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["a"] = de.read_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT.members["a"] + ) + + case 1: + kwargs["b"] = de.read_string( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT.members["b"] + ) + + case 2: + kwargs["c"] = _deserialize_string_list( + de, _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT.members["c"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT, consumer=_consumer + ) + return kwargs + + +NULL_AND_EMPTY_HEADERS_SERVER = APIOperation( + input=NullAndEmptyHeadersServerInput, + output=NullAndEmptyHeadersServerOutput, + schema=_SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER, + input_schema=_SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_INPUT, + output_schema=_SCHEMA_NULL_AND_EMPTY_HEADERS_SERVER_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class OmitsNullSerializesEmptyStringInput: + """Dataclass for OmitsNullSerializesEmptyStringInput structure.""" + + null_value: str | None = None + + empty_string: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.null_value is not None: + serializer.write_string( + _SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT.members["nullValue"], + self.null_value, + ) + + if self.empty_string is not None: + serializer.write_string( + _SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT.members["emptyString"], + self.empty_string, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["null_value"] = de.read_string( + _SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT.members[ + "nullValue" + ] + ) + + case 1: + kwargs["empty_string"] = de.read_string( + _SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT.members[ + "emptyString" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class OmitsNullSerializesEmptyStringOutput: + """Dataclass for OmitsNullSerializesEmptyStringOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_OUTPUT, consumer=_consumer + ) + return kwargs + + +OMITS_NULL_SERIALIZES_EMPTY_STRING = APIOperation( + input=OmitsNullSerializesEmptyStringInput, + output=OmitsNullSerializesEmptyStringOutput, + schema=_SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING, + input_schema=_SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_INPUT, + output_schema=_SCHEMA_OMITS_NULL_SERIALIZES_EMPTY_STRING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class OmitsSerializingEmptyListsInput: + """Dataclass for OmitsSerializingEmptyListsInput structure.""" + + query_string_list: list[str] | None = None + + query_integer_list: list[int] | None = None + + query_double_list: list[float] | None = None + + query_boolean_list: list[bool] | None = None + + query_timestamp_list: list[datetime] | None = None + + query_enum_list: list[str] | None = None + + query_integer_enum_list: list[int] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.query_string_list is not None: + _serialize_string_list( + serializer, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members["queryStringList"], + self.query_string_list, + ) + + if self.query_integer_list is not None: + _serialize_integer_list( + serializer, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members["queryIntegerList"], + self.query_integer_list, + ) + + if self.query_double_list is not None: + _serialize_double_list( + serializer, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members["queryDoubleList"], + self.query_double_list, + ) + + if self.query_boolean_list is not None: + _serialize_boolean_list( + serializer, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members["queryBooleanList"], + self.query_boolean_list, + ) + + if self.query_timestamp_list is not None: + _serialize_timestamp_list( + serializer, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members[ + "queryTimestampList" + ], + self.query_timestamp_list, + ) + + if self.query_enum_list is not None: + _serialize_foo_enum_list( + serializer, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members["queryEnumList"], + self.query_enum_list, + ) + + if self.query_integer_enum_list is not None: + _serialize_integer_enum_list( + serializer, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members[ + "queryIntegerEnumList" + ], + self.query_integer_enum_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["query_string_list"] = _deserialize_string_list( + de, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members[ + "queryStringList" + ], + ) + + case 1: + kwargs["query_integer_list"] = _deserialize_integer_list( + de, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members[ + "queryIntegerList" + ], + ) + + case 2: + kwargs["query_double_list"] = _deserialize_double_list( + de, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members[ + "queryDoubleList" + ], + ) + + case 3: + kwargs["query_boolean_list"] = _deserialize_boolean_list( + de, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members[ + "queryBooleanList" + ], + ) + + case 4: + kwargs["query_timestamp_list"] = _deserialize_timestamp_list( + de, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members[ + "queryTimestampList" + ], + ) + + case 5: + kwargs["query_enum_list"] = _deserialize_foo_enum_list( + de, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members[ + "queryEnumList" + ], + ) + + case 6: + kwargs["query_integer_enum_list"] = _deserialize_integer_enum_list( + de, + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT.members[ + "queryIntegerEnumList" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class OmitsSerializingEmptyListsOutput: + """Dataclass for OmitsSerializingEmptyListsOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_OUTPUT, consumer=_consumer + ) + return kwargs + + +OMITS_SERIALIZING_EMPTY_LISTS = APIOperation( + input=OmitsSerializingEmptyListsInput, + output=OmitsSerializingEmptyListsOutput, + schema=_SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS, + input_schema=_SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_INPUT, + output_schema=_SCHEMA_OMITS_SERIALIZING_EMPTY_LISTS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class OperationWithDefaultsInput: + """Dataclass for OperationWithDefaultsInput structure.""" + + defaults: Defaults | None = None + + client_optional_defaults: ClientOptionalDefaults | None = None + + top_level_default: str = "hi" + + other_top_level_default: int = 0 + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_DEFAULTS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.defaults is not None: + serializer.write_struct( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["defaults"], self.defaults + ) + + if self.client_optional_defaults is not None: + serializer.write_struct( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["clientOptionalDefaults"], + self.client_optional_defaults, + ) + + if self.top_level_default is not None: + serializer.write_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["topLevelDefault"], + self.top_level_default, + ) + + if self.other_top_level_default is not None: + serializer.write_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["otherTopLevelDefault"], + self.other_top_level_default, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["defaults"] = Defaults.deserialize(de) + + case 1: + kwargs["client_optional_defaults"] = ( + ClientOptionalDefaults.deserialize(de) + ) + + case 2: + kwargs["top_level_default"] = de.read_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members["topLevelDefault"] + ) + + case 3: + kwargs["other_top_level_default"] = de.read_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT.members[ + "otherTopLevelDefault" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_DEFAULTS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class OperationWithDefaultsOutput: + """Dataclass for OperationWithDefaultsOutput structure.""" + + default_string: str = "hi" + + default_boolean: bool = True + + default_list: list[str] = field(default_factory=list[str]) + + default_document_map: Document = field(default_factory=lambda: Document(dict())) + + default_document_string: Document = field(default_factory=lambda: Document("hi")) + + default_document_boolean: Document = field(default_factory=lambda: Document(True)) + + default_document_list: Document = field(default_factory=lambda: Document(list())) + + default_null_document: Document = field(default_factory=lambda: Document(None)) + + default_timestamp: datetime = datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc) + + default_blob: bytes = b64decode("YWJj") + + default_byte: int = 1 + + default_short: int = 1 + + default_integer: int = 10 + + default_long: int = 100 + + default_float: float = 1.0 + + default_double: float = 1.0 + + default_map: dict[str, str] = field(default_factory=dict[str, str]) + + default_enum: str = TestEnum("FOO") + + default_int_enum: int = TestIntEnum(1) + + empty_string: str = "" + + false_boolean: bool = False + + empty_blob: bytes = b64decode("") + + zero_byte: int = 0 + + zero_short: int = 0 + + zero_integer: int = 0 + + zero_long: int = 0 + + zero_float: float = 0.0 + + zero_double: float = 0.0 + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultString"], + self.default_string, + ) + serializer.write_boolean( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultBoolean"], + self.default_boolean, + ) + _serialize_test_string_list( + serializer, + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultList"], + self.default_list, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDocumentMap"], + self.default_document_map, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDocumentString"], + self.default_document_string, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDocumentBoolean"], + self.default_document_boolean, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDocumentList"], + self.default_document_list, + ) + serializer.write_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultNullDocument"], + self.default_null_document, + ) + serializer.write_timestamp( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultTimestamp"], + self.default_timestamp, + ) + serializer.write_blob( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultBlob"], + self.default_blob, + ) + serializer.write_byte( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultByte"], + self.default_byte, + ) + serializer.write_short( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultShort"], + self.default_short, + ) + serializer.write_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultInteger"], + self.default_integer, + ) + serializer.write_long( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultLong"], + self.default_long, + ) + serializer.write_float( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultFloat"], + self.default_float, + ) + serializer.write_double( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDouble"], + self.default_double, + ) + _serialize_test_string_map( + serializer, + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultMap"], + self.default_map, + ) + serializer.write_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultEnum"], + self.default_enum, + ) + serializer.write_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultIntEnum"], + self.default_int_enum, + ) + serializer.write_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["emptyString"], + self.empty_string, + ) + serializer.write_boolean( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["falseBoolean"], + self.false_boolean, + ) + serializer.write_blob( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["emptyBlob"], self.empty_blob + ) + serializer.write_byte( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroByte"], self.zero_byte + ) + serializer.write_short( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroShort"], self.zero_short + ) + serializer.write_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroInteger"], + self.zero_integer, + ) + serializer.write_long( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroLong"], self.zero_long + ) + serializer.write_float( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroFloat"], self.zero_float + ) + serializer.write_double( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroDouble"], + self.zero_double, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["default_string"] = de.read_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultString"] + ) + + case 1: + kwargs["default_boolean"] = de.read_boolean( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultBoolean"] + ) + + case 2: + kwargs["default_list"] = _deserialize_test_string_list( + de, + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultList"], + ) + + case 3: + kwargs["default_document_map"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultDocumentMap" + ] + ) + + case 4: + kwargs["default_document_string"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultDocumentString" + ] + ) + + case 5: + kwargs["default_document_boolean"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultDocumentBoolean" + ] + ) + + case 6: + kwargs["default_document_list"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultDocumentList" + ] + ) + + case 7: + kwargs["default_null_document"] = de.read_document( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultNullDocument" + ] + ) + + case 8: + kwargs["default_timestamp"] = de.read_timestamp( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultTimestamp" + ] + ) + + case 9: + kwargs["default_blob"] = de.read_blob( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultBlob"] + ) + + case 10: + kwargs["default_byte"] = de.read_byte( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultByte"] + ) + + case 11: + kwargs["default_short"] = de.read_short( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultShort"] + ) + + case 12: + kwargs["default_integer"] = de.read_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultInteger"] + ) + + case 13: + kwargs["default_long"] = de.read_long( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultLong"] + ) + + case 14: + kwargs["default_float"] = de.read_float( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultFloat"] + ) + + case 15: + kwargs["default_double"] = de.read_double( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultDouble"] + ) + + case 16: + kwargs["default_map"] = _deserialize_test_string_map( + de, _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["defaultMap"] + ) + + case 17: + kwargs["default_enum"] = TestEnum( + de.read_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultEnum" + ] + ) + ) + + case 18: + kwargs["default_int_enum"] = TestIntEnum( + de.read_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members[ + "defaultIntEnum" + ] + ) + ) + + case 19: + kwargs["empty_string"] = de.read_string( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["emptyString"] + ) + + case 20: + kwargs["false_boolean"] = de.read_boolean( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["falseBoolean"] + ) + + case 21: + kwargs["empty_blob"] = de.read_blob( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["emptyBlob"] + ) + + case 22: + kwargs["zero_byte"] = de.read_byte( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroByte"] + ) + + case 23: + kwargs["zero_short"] = de.read_short( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroShort"] + ) + + case 24: + kwargs["zero_integer"] = de.read_integer( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroInteger"] + ) + + case 25: + kwargs["zero_long"] = de.read_long( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroLong"] + ) + + case 26: + kwargs["zero_float"] = de.read_float( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroFloat"] + ) + + case 27: + kwargs["zero_double"] = de.read_double( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT.members["zeroDouble"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT, consumer=_consumer + ) + return kwargs + + +OPERATION_WITH_DEFAULTS = APIOperation( + input=OperationWithDefaultsInput, + output=OperationWithDefaultsOutput, + schema=_SCHEMA_OPERATION_WITH_DEFAULTS, + input_schema=_SCHEMA_OPERATION_WITH_DEFAULTS_INPUT, + output_schema=_SCHEMA_OPERATION_WITH_DEFAULTS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TopLevel: + """Dataclass for TopLevel structure.""" + + dialog: Dialog + + dialog_list: list[Dialog] = field(default_factory=list[Dialog]) + + dialog_map: dict[str, Dialog] = field(default_factory=dict[str, Dialog]) + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TOP_LEVEL, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TOP_LEVEL.members["dialog"], self.dialog) + _serialize_dialog_list( + serializer, _SCHEMA_TOP_LEVEL.members["dialogList"], self.dialog_list + ) + _serialize_dialog_map( + serializer, _SCHEMA_TOP_LEVEL.members["dialogMap"], self.dialog_map + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["dialog"] = Dialog.deserialize(de) + + case 1: + kwargs["dialog_list"] = _deserialize_dialog_list( + de, _SCHEMA_TOP_LEVEL.members["dialogList"] + ) + + case 2: + kwargs["dialog_map"] = _deserialize_dialog_map( + de, _SCHEMA_TOP_LEVEL.members["dialogMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TOP_LEVEL, consumer=_consumer) + if "dialog" not in kwargs: + kwargs["dialog"] = Dialog._smithy_default() + return kwargs + + +@dataclass(kw_only=True) +class OperationWithNestedStructureInput: + """Dataclass for OperationWithNestedStructureInput structure.""" + + top_level: TopLevel | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.top_level is not None: + serializer.write_struct( + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT.members["topLevel"], + self.top_level, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["top_level"] = TopLevel.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class OperationWithNestedStructureOutput: + """Dataclass for OperationWithNestedStructureOutput structure.""" + + dialog: Dialog + + dialog_list: list[Dialog] = field(default_factory=list[Dialog]) + + dialog_map: dict[str, Dialog] = field(default_factory=dict[str, Dialog]) + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members["dialog"], + self.dialog, + ) + _serialize_dialog_list( + serializer, + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members["dialogList"], + self.dialog_list, + ) + _serialize_dialog_map( + serializer, + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members["dialogMap"], + self.dialog_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["dialog"] = Dialog.deserialize(de) + + case 1: + kwargs["dialog_list"] = _deserialize_dialog_list( + de, + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members[ + "dialogList" + ], + ) + + case 2: + kwargs["dialog_map"] = _deserialize_dialog_map( + de, + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT.members[ + "dialogMap" + ], + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT, consumer=_consumer + ) + if "dialog" not in kwargs: + kwargs["dialog"] = Dialog._smithy_default() + return kwargs + + +OPERATION_WITH_NESTED_STRUCTURE = APIOperation( + input=OperationWithNestedStructureInput, + output=OperationWithNestedStructureOutput, + schema=_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE, + input_schema=_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_INPUT, + output_schema=_SCHEMA_OPERATION_WITH_NESTED_STRUCTURE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class OutputStreamInput: + """Dataclass for OutputStreamInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OUTPUT_STREAM_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_OUTPUT_STREAM_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class OutputStreamOutput: + """Dataclass for OutputStreamOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OUTPUT_STREAM_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_OUTPUT_STREAM_OUTPUT, consumer=_consumer) + return kwargs + + +OUTPUT_STREAM = APIOperation( + input=OutputStreamInput, + output=OutputStreamOutput, + schema=_SCHEMA_OUTPUT_STREAM, + input_schema=_SCHEMA_OUTPUT_STREAM_INPUT, + output_schema=_SCHEMA_OUTPUT_STREAM_OUTPUT, + error_registry=TypeRegistry( + { + ShapeID( + "aws.protocoltests.restjson#ServiceUnavailableError" + ): ServiceUnavailableError + } + ), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[_SCHEMA_SERVICE_UNAVAILABLE_ERROR], +) + + +@dataclass(kw_only=True) +class OutputStreamWithInitialResponseInput: + """Dataclass for OutputStreamWithInitialResponseInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class OutputStreamWithInitialResponseOutput: + """Dataclass for OutputStreamWithInitialResponseOutput structure.""" + + initial_response_member: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_OUTPUT, self + ) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string( + _SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_OUTPUT.members[ + "initialResponseMember" + ], + self.initial_response_member, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["initial_response_member"] = de.read_string( + _SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_OUTPUT.members[ + "initialResponseMember" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_OUTPUT, consumer=_consumer + ) + if "initial_response_member" not in kwargs: + kwargs["initial_response_member"] = "" + return kwargs + + +OUTPUT_STREAM_WITH_INITIAL_RESPONSE = APIOperation( + input=OutputStreamWithInitialResponseInput, + output=OutputStreamWithInitialResponseOutput, + schema=_SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE, + input_schema=_SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_INPUT, + output_schema=_SCHEMA_OUTPUT_STREAM_WITH_INITIAL_RESPONSE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class PayloadConfig: + """Dataclass for PayloadConfig structure.""" + + data: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PAYLOAD_CONFIG, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.data is not None: + serializer.write_integer(_SCHEMA_PAYLOAD_CONFIG.members["data"], self.data) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["data"] = de.read_integer( + _SCHEMA_PAYLOAD_CONFIG.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_PAYLOAD_CONFIG, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class Unit: + """Dataclass for Unit structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_UNIT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_UNIT, consumer=_consumer) + return kwargs + + +@dataclass +class PlayerActionQuit: + """Quit the game.""" + + value: Unit + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PLAYER_ACTION, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PLAYER_ACTION.members["quit"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(value=Unit.deserialize(deserializer)) + + +@dataclass +class PlayerActionUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +PlayerAction = Union[PlayerActionQuit | PlayerActionUnknown] + + +class _PlayerActionDeserializer: + _result: PlayerAction | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> PlayerAction: + self._result = None + deserializer.read_struct(_SCHEMA_PLAYER_ACTION, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(PlayerActionQuit.deserialize(de)) + + case _: + self._set_result(PlayerActionUnknown(tag=schema.expect_member_name())) + + def _set_result(self, value: PlayerAction) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class PostPlayerActionInput: + """Dataclass for PostPlayerActionInput structure.""" + + action: PlayerAction | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_POST_PLAYER_ACTION_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.action is not None: + serializer.write_struct( + _SCHEMA_POST_PLAYER_ACTION_INPUT.members["action"], self.action + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["action"] = _PlayerActionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_POST_PLAYER_ACTION_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class PostPlayerActionOutput: + """Dataclass for PostPlayerActionOutput structure.""" + + action: PlayerAction + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_POST_PLAYER_ACTION_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_POST_PLAYER_ACTION_OUTPUT.members["action"], self.action + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["action"] = _PlayerActionDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_POST_PLAYER_ACTION_OUTPUT, consumer=_consumer) + if "action" not in kwargs: + kwargs["action"] = PlayerActionUnknown(tag="") + return kwargs + + +POST_PLAYER_ACTION = APIOperation( + input=PostPlayerActionInput, + output=PostPlayerActionOutput, + schema=_SCHEMA_POST_PLAYER_ACTION, + input_schema=_SCHEMA_POST_PLAYER_ACTION_INPUT, + output_schema=_SCHEMA_POST_PLAYER_ACTION_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass +class UnionWithJsonNameFoo: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_UNION_WITH_JSON_NAME, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_UNION_WITH_JSON_NAME.members["foo"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_UNION_WITH_JSON_NAME.members["foo"]) + ) + + +@dataclass +class UnionWithJsonNameBar: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_UNION_WITH_JSON_NAME, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_UNION_WITH_JSON_NAME.members["bar"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_UNION_WITH_JSON_NAME.members["bar"]) + ) + + +@dataclass +class UnionWithJsonNameBaz: + value: str + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_UNION_WITH_JSON_NAME, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_string(_SCHEMA_UNION_WITH_JSON_NAME.members["baz"], self.value) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls( + value=deserializer.read_string(_SCHEMA_UNION_WITH_JSON_NAME.members["baz"]) + ) + + +@dataclass +class UnionWithJsonNameUnknown: + """ + Represents an unknown variant. + + If you receive this value, you will need to update your library to receive the + parsed value. + + This value may not be deliberately sent. + """ + + tag: str + + def serialize(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + def serialize_members(self, serializer: ShapeSerializer): + raise SerializationError("Unknown union variants may not be serialized.") + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + raise NotImplementedError() + + +UnionWithJsonName = Union[ + UnionWithJsonNameFoo + | UnionWithJsonNameBar + | UnionWithJsonNameBaz + | UnionWithJsonNameUnknown +] + + +class _UnionWithJsonNameDeserializer: + _result: UnionWithJsonName | None = None + + def deserialize(self, deserializer: ShapeDeserializer) -> UnionWithJsonName: + self._result = None + deserializer.read_struct(_SCHEMA_UNION_WITH_JSON_NAME, self._consumer) + + if self._result is None: + raise SerializationError( + "Unions must have exactly one value, but found none." + ) + + return self._result + + def _consumer(self, schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + self._set_result(UnionWithJsonNameFoo.deserialize(de)) + + case 1: + self._set_result(UnionWithJsonNameBar.deserialize(de)) + + case 2: + self._set_result(UnionWithJsonNameBaz.deserialize(de)) + + case _: + self._set_result( + UnionWithJsonNameUnknown(tag=schema.expect_member_name()) + ) + + def _set_result(self, value: UnionWithJsonName) -> None: + if self._result is not None: + raise SerializationError( + "Unions must have exactly one value, but found more than one." + ) + self._result = value + + +@dataclass(kw_only=True) +class PostUnionWithJsonNameInput: + """Dataclass for PostUnionWithJsonNameInput structure.""" + + value: UnionWithJsonName | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_POST_UNION_WITH_JSON_NAME_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.value is not None: + serializer.write_struct( + _SCHEMA_POST_UNION_WITH_JSON_NAME_INPUT.members["value"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = _UnionWithJsonNameDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_POST_UNION_WITH_JSON_NAME_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class PostUnionWithJsonNameOutput: + """Dataclass for PostUnionWithJsonNameOutput structure.""" + + value: UnionWithJsonName + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_POST_UNION_WITH_JSON_NAME_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_struct( + _SCHEMA_POST_UNION_WITH_JSON_NAME_OUTPUT.members["value"], self.value + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["value"] = _UnionWithJsonNameDeserializer().deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_POST_UNION_WITH_JSON_NAME_OUTPUT, consumer=_consumer + ) + if "value" not in kwargs: + kwargs["value"] = UnionWithJsonNameUnknown(tag="") + return kwargs + + +POST_UNION_WITH_JSON_NAME = APIOperation( + input=PostUnionWithJsonNameInput, + output=PostUnionWithJsonNameOutput, + schema=_SCHEMA_POST_UNION_WITH_JSON_NAME, + input_schema=_SCHEMA_POST_UNION_WITH_JSON_NAME_INPUT, + output_schema=_SCHEMA_POST_UNION_WITH_JSON_NAME_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class PutWithContentEncodingInput: + """Dataclass for PutWithContentEncodingInput structure.""" + + encoding: str | None = None + + data: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.encoding is not None: + serializer.write_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["encoding"], + self.encoding, + ) + + if self.data is not None: + serializer.write_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["data"], self.data + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["encoding"] = de.read_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["encoding"] + ) + + case 1: + kwargs["data"] = de.read_string( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class PutWithContentEncodingOutput: + """Dataclass for PutWithContentEncodingOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, consumer=_consumer + ) + return kwargs + + +PUT_WITH_CONTENT_ENCODING = APIOperation( + input=PutWithContentEncodingInput, + output=PutWithContentEncodingOutput, + schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING, + input_schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING_INPUT, + output_schema=_SCHEMA_PUT_WITH_CONTENT_ENCODING_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class QueryIdempotencyTokenAutoFillInput: + """Dataclass for QueryIdempotencyTokenAutoFillInput structure.""" + + token: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.token is not None: + serializer.write_string( + _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT.members["token"], + self.token, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["token"] = de.read_string( + _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT.members["token"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class QueryIdempotencyTokenAutoFillOutput: + """Dataclass for QueryIdempotencyTokenAutoFillOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT, consumer=_consumer + ) + return kwargs + + +QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL = APIOperation( + input=QueryIdempotencyTokenAutoFillInput, + output=QueryIdempotencyTokenAutoFillOutput, + schema=_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL, + input_schema=_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_INPUT, + output_schema=_SCHEMA_QUERY_IDEMPOTENCY_TOKEN_AUTO_FILL_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class QueryParamsAsStringListMapInput: + """Dataclass for QueryParamsAsStringListMapInput structure.""" + + qux: str | None = None + + foo: dict[str, list[str]] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.qux is not None: + serializer.write_string( + _SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT.members["qux"], self.qux + ) + + if self.foo is not None: + _serialize_string_list_map( + serializer, + _SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT.members["foo"], + self.foo, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["qux"] = de.read_string( + _SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT.members["qux"] + ) + + case 1: + kwargs["foo"] = _deserialize_string_list_map( + de, _SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT.members["foo"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class QueryParamsAsStringListMapOutput: + """Dataclass for QueryParamsAsStringListMapOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_OUTPUT, consumer=_consumer + ) + return kwargs + + +QUERY_PARAMS_AS_STRING_LIST_MAP = APIOperation( + input=QueryParamsAsStringListMapInput, + output=QueryParamsAsStringListMapOutput, + schema=_SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP, + input_schema=_SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_INPUT, + output_schema=_SCHEMA_QUERY_PARAMS_AS_STRING_LIST_MAP_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class QueryPrecedenceInput: + """Dataclass for QueryPrecedenceInput structure.""" + + foo: str | None = None + + baz: dict[str, str] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_PRECEDENCE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_QUERY_PRECEDENCE_INPUT.members["foo"], self.foo + ) + + if self.baz is not None: + _serialize_string_map( + serializer, _SCHEMA_QUERY_PRECEDENCE_INPUT.members["baz"], self.baz + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_QUERY_PRECEDENCE_INPUT.members["foo"] + ) + + case 1: + kwargs["baz"] = _deserialize_string_map( + de, _SCHEMA_QUERY_PRECEDENCE_INPUT.members["baz"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_QUERY_PRECEDENCE_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class QueryPrecedenceOutput: + """Dataclass for QueryPrecedenceOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_QUERY_PRECEDENCE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_QUERY_PRECEDENCE_OUTPUT, consumer=_consumer) + return kwargs + + +QUERY_PRECEDENCE = APIOperation( + input=QueryPrecedenceInput, + output=QueryPrecedenceOutput, + schema=_SCHEMA_QUERY_PRECEDENCE, + input_schema=_SCHEMA_QUERY_PRECEDENCE_INPUT, + output_schema=_SCHEMA_QUERY_PRECEDENCE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class ResponseCodeHttpFallbackInput: + """Dataclass for ResponseCodeHttpFallbackInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RESPONSE_CODE_HTTP_FALLBACK_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_RESPONSE_CODE_HTTP_FALLBACK_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class ResponseCodeHttpFallbackOutput: + """Dataclass for ResponseCodeHttpFallbackOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RESPONSE_CODE_HTTP_FALLBACK_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_RESPONSE_CODE_HTTP_FALLBACK_OUTPUT, consumer=_consumer + ) + return kwargs + + +RESPONSE_CODE_HTTP_FALLBACK = APIOperation( + input=ResponseCodeHttpFallbackInput, + output=ResponseCodeHttpFallbackOutput, + schema=_SCHEMA_RESPONSE_CODE_HTTP_FALLBACK, + input_schema=_SCHEMA_RESPONSE_CODE_HTTP_FALLBACK_INPUT, + output_schema=_SCHEMA_RESPONSE_CODE_HTTP_FALLBACK_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class ResponseCodeRequiredInput: + """Dataclass for ResponseCodeRequiredInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RESPONSE_CODE_REQUIRED_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_RESPONSE_CODE_REQUIRED_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class ResponseCodeRequiredOutput: + """Dataclass for ResponseCodeRequiredOutput structure.""" + + response_code: int + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RESPONSE_CODE_REQUIRED_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + serializer.write_integer( + _SCHEMA_RESPONSE_CODE_REQUIRED_OUTPUT.members["responseCode"], + self.response_code, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["response_code"] = de.read_integer( + _SCHEMA_RESPONSE_CODE_REQUIRED_OUTPUT.members["responseCode"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_RESPONSE_CODE_REQUIRED_OUTPUT, consumer=_consumer + ) + if "response_code" not in kwargs: + kwargs["response_code"] = 0 + return kwargs + + +RESPONSE_CODE_REQUIRED = APIOperation( + input=ResponseCodeRequiredInput, + output=ResponseCodeRequiredOutput, + schema=_SCHEMA_RESPONSE_CODE_REQUIRED, + input_schema=_SCHEMA_RESPONSE_CODE_REQUIRED_INPUT, + output_schema=_SCHEMA_RESPONSE_CODE_REQUIRED_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class SimpleScalarPropertiesInput: + """Dataclass for SimpleScalarPropertiesInput structure.""" + + foo: str | None = None + + string_value: str | None = None + + true_boolean_value: bool | None = None + + false_boolean_value: bool | None = None + + byte_value: int | None = None + + short_value: int | None = None + + integer_value: int | None = None + + long_value: int | None = None + + float_value: float | None = None + + double_value: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["foo"], self.foo + ) + + if self.string_value is not None: + serializer.write_string( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["stringValue"], + self.string_value, + ) + + if self.true_boolean_value is not None: + serializer.write_boolean( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["trueBooleanValue"], + self.true_boolean_value, + ) + + if self.false_boolean_value is not None: + serializer.write_boolean( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["falseBooleanValue"], + self.false_boolean_value, + ) + + if self.byte_value is not None: + serializer.write_byte( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["byteValue"], + self.byte_value, + ) + + if self.short_value is not None: + serializer.write_short( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["shortValue"], + self.short_value, + ) + + if self.integer_value is not None: + serializer.write_integer( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["integerValue"], + self.integer_value, + ) + + if self.long_value is not None: + serializer.write_long( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["longValue"], + self.long_value, + ) + + if self.float_value is not None: + serializer.write_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["floatValue"], + self.float_value, + ) + + if self.double_value is not None: + serializer.write_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["doubleValue"], + self.double_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["foo"] + ) + + case 1: + kwargs["string_value"] = de.read_string( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["stringValue"] + ) + + case 2: + kwargs["true_boolean_value"] = de.read_boolean( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members[ + "trueBooleanValue" + ] + ) + + case 3: + kwargs["false_boolean_value"] = de.read_boolean( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members[ + "falseBooleanValue" + ] + ) + + case 4: + kwargs["byte_value"] = de.read_byte( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["byteValue"] + ) + + case 5: + kwargs["short_value"] = de.read_short( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["shortValue"] + ) + + case 6: + kwargs["integer_value"] = de.read_integer( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["integerValue"] + ) + + case 7: + kwargs["long_value"] = de.read_long( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["longValue"] + ) + + case 8: + kwargs["float_value"] = de.read_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["floatValue"] + ) + + case 9: + kwargs["double_value"] = de.read_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT.members["doubleValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class SimpleScalarPropertiesOutput: + """Dataclass for SimpleScalarPropertiesOutput structure.""" + + foo: str | None = None + + string_value: str | None = None + + true_boolean_value: bool | None = None + + false_boolean_value: bool | None = None + + byte_value: int | None = None + + short_value: int | None = None + + integer_value: int | None = None + + long_value: int | None = None + + float_value: float | None = None + + double_value: float | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["foo"], self.foo + ) + + if self.string_value is not None: + serializer.write_string( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["stringValue"], + self.string_value, + ) + + if self.true_boolean_value is not None: + serializer.write_boolean( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["trueBooleanValue"], + self.true_boolean_value, + ) + + if self.false_boolean_value is not None: + serializer.write_boolean( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["falseBooleanValue"], + self.false_boolean_value, + ) + + if self.byte_value is not None: + serializer.write_byte( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["byteValue"], + self.byte_value, + ) + + if self.short_value is not None: + serializer.write_short( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["shortValue"], + self.short_value, + ) + + if self.integer_value is not None: + serializer.write_integer( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["integerValue"], + self.integer_value, + ) + + if self.long_value is not None: + serializer.write_long( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["longValue"], + self.long_value, + ) + + if self.float_value is not None: + serializer.write_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["floatValue"], + self.float_value, + ) + + if self.double_value is not None: + serializer.write_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["doubleValue"], + self.double_value, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["foo"] + ) + + case 1: + kwargs["string_value"] = de.read_string( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["stringValue"] + ) + + case 2: + kwargs["true_boolean_value"] = de.read_boolean( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members[ + "trueBooleanValue" + ] + ) + + case 3: + kwargs["false_boolean_value"] = de.read_boolean( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members[ + "falseBooleanValue" + ] + ) + + case 4: + kwargs["byte_value"] = de.read_byte( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["byteValue"] + ) + + case 5: + kwargs["short_value"] = de.read_short( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["shortValue"] + ) + + case 6: + kwargs["integer_value"] = de.read_integer( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["integerValue"] + ) + + case 7: + kwargs["long_value"] = de.read_long( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["longValue"] + ) + + case 8: + kwargs["float_value"] = de.read_float( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["floatValue"] + ) + + case 9: + kwargs["double_value"] = de.read_double( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT.members["doubleValue"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, consumer=_consumer + ) + return kwargs + + +SIMPLE_SCALAR_PROPERTIES = APIOperation( + input=SimpleScalarPropertiesInput, + output=SimpleScalarPropertiesOutput, + schema=_SCHEMA_SIMPLE_SCALAR_PROPERTIES, + input_schema=_SCHEMA_SIMPLE_SCALAR_PROPERTIES_INPUT, + output_schema=_SCHEMA_SIMPLE_SCALAR_PROPERTIES_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_sparse_short_list( + serializer: ShapeSerializer, schema: Schema, value: list[int | None] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + if e is None: + ls.write_null(member_schema) + else: + ls.write_short(member_schema, e) + + +def _deserialize_sparse_short_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[int | None]: + result: list[int | None] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + result.append(None) + else: + result.append(d.read_short(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +def _serialize_sparse_string_list( + serializer: ShapeSerializer, schema: Schema, value: list[str | None] +) -> None: + member_schema = schema.members["member"] + with serializer.begin_list(schema, len(value)) as ls: + for e in value: + if e is None: + ls.write_null(member_schema) + else: + ls.write_string(member_schema, e) + + +def _deserialize_sparse_string_list( + deserializer: ShapeDeserializer, schema: Schema +) -> list[str | None]: + result: list[str | None] = [] + member_schema = schema.members["member"] + + def _read_value(d: ShapeDeserializer): + if d.is_null(): + d.read_null() + result.append(None) + else: + result.append(d.read_string(member_schema)) + + deserializer.read_list(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class SparseJsonListsInput: + """Dataclass for SparseJsonListsInput structure.""" + + sparse_string_list: list[str | None] | None = None + + sparse_short_list: list[int | None] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SPARSE_JSON_LISTS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.sparse_string_list is not None: + _serialize_sparse_string_list( + serializer, + _SCHEMA_SPARSE_JSON_LISTS_INPUT.members["sparseStringList"], + self.sparse_string_list, + ) + + if self.sparse_short_list is not None: + _serialize_sparse_short_list( + serializer, + _SCHEMA_SPARSE_JSON_LISTS_INPUT.members["sparseShortList"], + self.sparse_short_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["sparse_string_list"] = _deserialize_sparse_string_list( + de, _SCHEMA_SPARSE_JSON_LISTS_INPUT.members["sparseStringList"] + ) + + case 1: + kwargs["sparse_short_list"] = _deserialize_sparse_short_list( + de, _SCHEMA_SPARSE_JSON_LISTS_INPUT.members["sparseShortList"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_SPARSE_JSON_LISTS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class SparseJsonListsOutput: + """Dataclass for SparseJsonListsOutput structure.""" + + sparse_string_list: list[str | None] | None = None + + sparse_short_list: list[int | None] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SPARSE_JSON_LISTS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.sparse_string_list is not None: + _serialize_sparse_string_list( + serializer, + _SCHEMA_SPARSE_JSON_LISTS_OUTPUT.members["sparseStringList"], + self.sparse_string_list, + ) + + if self.sparse_short_list is not None: + _serialize_sparse_short_list( + serializer, + _SCHEMA_SPARSE_JSON_LISTS_OUTPUT.members["sparseShortList"], + self.sparse_short_list, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["sparse_string_list"] = _deserialize_sparse_string_list( + de, _SCHEMA_SPARSE_JSON_LISTS_OUTPUT.members["sparseStringList"] + ) + + case 1: + kwargs["sparse_short_list"] = _deserialize_sparse_short_list( + de, _SCHEMA_SPARSE_JSON_LISTS_OUTPUT.members["sparseShortList"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_SPARSE_JSON_LISTS_OUTPUT, consumer=_consumer) + return kwargs + + +SPARSE_JSON_LISTS = APIOperation( + input=SparseJsonListsInput, + output=SparseJsonListsOutput, + schema=_SCHEMA_SPARSE_JSON_LISTS, + input_schema=_SCHEMA_SPARSE_JSON_LISTS_INPUT, + output_schema=_SCHEMA_SPARSE_JSON_LISTS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +def _serialize_sparse_boolean_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, bool | None] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + if v is None: + m.entry(k, lambda vs: vs.write_null(value_schema)) + else: + m.entry(k, lambda vs: vs.write_boolean(value_schema, v)) # type: ignore + + +def _deserialize_sparse_boolean_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, bool | None]: + result: dict[str, bool | None] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + result[k] = None + else: + result[k] = d.read_boolean(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_sparse_number_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, int | None] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + if v is None: + m.entry(k, lambda vs: vs.write_null(value_schema)) + else: + m.entry(k, lambda vs: vs.write_integer(value_schema, v)) # type: ignore + + +def _deserialize_sparse_number_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, int | None]: + result: dict[str, int | None] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + result[k] = None + else: + result[k] = d.read_integer(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_sparse_set_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, list[str] | None] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + if v is None: + m.entry(k, lambda vs: vs.write_null(value_schema)) + else: + m.entry(k, lambda vs: _serialize_string_set(vs, value_schema, v)) # type: ignore + + +def _deserialize_sparse_set_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, list[str] | None]: + result: dict[str, list[str] | None] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + result[k] = None + else: + result[k] = _deserialize_string_set(d, value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_sparse_string_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, str | None] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + if v is None: + m.entry(k, lambda vs: vs.write_null(value_schema)) + else: + m.entry(k, lambda vs: vs.write_string(value_schema, v)) # type: ignore + + +def _deserialize_sparse_string_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, str | None]: + result: dict[str, str | None] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + result[k] = None + else: + result[k] = d.read_string(value_schema) + + deserializer.read_map(schema, _read_value) + return result + + +def _serialize_sparse_struct_map( + serializer: ShapeSerializer, schema: Schema, value: dict[str, GreetingStruct | None] +) -> None: + with serializer.begin_map(schema, len(value)) as m: + value_schema = schema.members["value"] + for k, v in value.items(): + if v is None: + m.entry(k, lambda vs: vs.write_null(value_schema)) + else: + m.entry(k, lambda vs: vs.write_struct(value_schema, v)) # type: ignore + + +def _deserialize_sparse_struct_map( + deserializer: ShapeDeserializer, schema: Schema +) -> dict[str, GreetingStruct | None]: + result: dict[str, GreetingStruct | None] = {} + value_schema = schema.members["value"] + + def _read_value(k: str, d: ShapeDeserializer): + if d.is_null(): + d.read_null() + result[k] = None + else: + result[k] = GreetingStruct.deserialize(d) + + deserializer.read_map(schema, _read_value) + return result + + +@dataclass(kw_only=True) +class SparseJsonMapsInput: + """Dataclass for SparseJsonMapsInput structure.""" + + sparse_struct_map: dict[str, GreetingStruct | None] | None = None + + sparse_number_map: dict[str, int | None] | None = None + + sparse_boolean_map: dict[str, bool | None] | None = None + + sparse_string_map: dict[str, str | None] | None = None + + sparse_set_map: dict[str, list[str] | None] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SPARSE_JSON_MAPS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.sparse_struct_map is not None: + _serialize_sparse_struct_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseStructMap"], + self.sparse_struct_map, + ) + + if self.sparse_number_map is not None: + _serialize_sparse_number_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseNumberMap"], + self.sparse_number_map, + ) + + if self.sparse_boolean_map is not None: + _serialize_sparse_boolean_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseBooleanMap"], + self.sparse_boolean_map, + ) + + if self.sparse_string_map is not None: + _serialize_sparse_string_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseStringMap"], + self.sparse_string_map, + ) + + if self.sparse_set_map is not None: + _serialize_sparse_set_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseSetMap"], + self.sparse_set_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["sparse_struct_map"] = _deserialize_sparse_struct_map( + de, _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseStructMap"] + ) + + case 1: + kwargs["sparse_number_map"] = _deserialize_sparse_number_map( + de, _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseNumberMap"] + ) + + case 2: + kwargs["sparse_boolean_map"] = _deserialize_sparse_boolean_map( + de, _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseBooleanMap"] + ) + + case 3: + kwargs["sparse_string_map"] = _deserialize_sparse_string_map( + de, _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseStringMap"] + ) + + case 4: + kwargs["sparse_set_map"] = _deserialize_sparse_set_map( + de, _SCHEMA_SPARSE_JSON_MAPS_INPUT.members["sparseSetMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_SPARSE_JSON_MAPS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class SparseJsonMapsOutput: + """Dataclass for SparseJsonMapsOutput structure.""" + + sparse_struct_map: dict[str, GreetingStruct | None] | None = None + + sparse_number_map: dict[str, int | None] | None = None + + sparse_boolean_map: dict[str, bool | None] | None = None + + sparse_string_map: dict[str, str | None] | None = None + + sparse_set_map: dict[str, list[str] | None] | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_SPARSE_JSON_MAPS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.sparse_struct_map is not None: + _serialize_sparse_struct_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseStructMap"], + self.sparse_struct_map, + ) + + if self.sparse_number_map is not None: + _serialize_sparse_number_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseNumberMap"], + self.sparse_number_map, + ) + + if self.sparse_boolean_map is not None: + _serialize_sparse_boolean_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseBooleanMap"], + self.sparse_boolean_map, + ) + + if self.sparse_string_map is not None: + _serialize_sparse_string_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseStringMap"], + self.sparse_string_map, + ) + + if self.sparse_set_map is not None: + _serialize_sparse_set_map( + serializer, + _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseSetMap"], + self.sparse_set_map, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["sparse_struct_map"] = _deserialize_sparse_struct_map( + de, _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseStructMap"] + ) + + case 1: + kwargs["sparse_number_map"] = _deserialize_sparse_number_map( + de, _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseNumberMap"] + ) + + case 2: + kwargs["sparse_boolean_map"] = _deserialize_sparse_boolean_map( + de, _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseBooleanMap"] + ) + + case 3: + kwargs["sparse_string_map"] = _deserialize_sparse_string_map( + de, _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseStringMap"] + ) + + case 4: + kwargs["sparse_set_map"] = _deserialize_sparse_set_map( + de, _SCHEMA_SPARSE_JSON_MAPS_OUTPUT.members["sparseSetMap"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_SPARSE_JSON_MAPS_OUTPUT, consumer=_consumer) + return kwargs + + +SPARSE_JSON_MAPS = APIOperation( + input=SparseJsonMapsInput, + output=SparseJsonMapsOutput, + schema=_SCHEMA_SPARSE_JSON_MAPS, + input_schema=_SCHEMA_SPARSE_JSON_MAPS_INPUT, + output_schema=_SCHEMA_SPARSE_JSON_MAPS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class StreamingTraitsInput: + """Dataclass for StreamingTraitsInput structure.""" + + foo: str | None = None + + blob: StreamingBlob = b64decode("") + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STREAMING_TRAITS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_STREAMING_TRAITS_INPUT.members["foo"], self.foo + ) + + if self.blob is not None: + serializer.write_data_stream( + _SCHEMA_STREAMING_TRAITS_INPUT.members["blob"], self.blob + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_STREAMING_TRAITS_INPUT.members["foo"] + ) + + case 1: + kwargs["blob"] = de.read_data_stream( + _SCHEMA_STREAMING_TRAITS_INPUT.members["blob"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_STREAMING_TRAITS_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class StreamingTraitsOutput: + """Dataclass for StreamingTraitsOutput structure.""" + + foo: str | None = None + + blob: StreamingBlob = b64decode("") + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STREAMING_TRAITS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_STREAMING_TRAITS_OUTPUT.members["foo"], self.foo + ) + + serializer.write_data_stream( + _SCHEMA_STREAMING_TRAITS_OUTPUT.members["blob"], self.blob + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_STREAMING_TRAITS_OUTPUT.members["foo"] + ) + + case 1: + kwargs["blob"] = de.read_data_stream( + _SCHEMA_STREAMING_TRAITS_OUTPUT.members["blob"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_STREAMING_TRAITS_OUTPUT, consumer=_consumer) + return kwargs + + +STREAMING_TRAITS = APIOperation( + input=StreamingTraitsInput, + output=StreamingTraitsOutput, + schema=_SCHEMA_STREAMING_TRAITS, + input_schema=_SCHEMA_STREAMING_TRAITS_INPUT, + output_schema=_SCHEMA_STREAMING_TRAITS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class StreamingTraitsRequireLengthInput: + """Dataclass for StreamingTraitsRequireLengthInput structure.""" + + foo: str | None = None + + blob: StreamingBlob = b64decode("") + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_INPUT.members["foo"], self.foo + ) + + if self.blob is not None: + serializer.write_data_stream( + _SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_INPUT.members["blob"], self.blob + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_INPUT.members["foo"] + ) + + case 1: + kwargs["blob"] = de.read_data_stream( + _SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_INPUT.members["blob"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class StreamingTraitsRequireLengthOutput: + """Dataclass for StreamingTraitsRequireLengthOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_OUTPUT, consumer=_consumer + ) + return kwargs + + +STREAMING_TRAITS_REQUIRE_LENGTH = APIOperation( + input=StreamingTraitsRequireLengthInput, + output=StreamingTraitsRequireLengthOutput, + schema=_SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH, + input_schema=_SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_INPUT, + output_schema=_SCHEMA_STREAMING_TRAITS_REQUIRE_LENGTH_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class StreamingTraitsWithMediaTypeInput: + """Dataclass for StreamingTraitsWithMediaTypeInput structure.""" + + foo: str | None = None + + blob: StreamingBlob = b64decode("") + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT.members["foo"], self.foo + ) + + if self.blob is not None: + serializer.write_data_stream( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT.members["blob"], + self.blob, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT.members["foo"] + ) + + case 1: + kwargs["blob"] = de.read_data_stream( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT.members["blob"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class StreamingTraitsWithMediaTypeOutput: + """Dataclass for StreamingTraitsWithMediaTypeOutput structure.""" + + foo: str | None = None + + blob: StreamingBlob = b64decode("") + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT.members["foo"], self.foo + ) + + serializer.write_data_stream( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT.members["blob"], self.blob + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT.members["foo"] + ) + + case 1: + kwargs["blob"] = de.read_data_stream( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT.members["blob"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT, consumer=_consumer + ) + return kwargs + + +STREAMING_TRAITS_WITH_MEDIA_TYPE = APIOperation( + input=StreamingTraitsWithMediaTypeInput, + output=StreamingTraitsWithMediaTypeOutput, + schema=_SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE, + input_schema=_SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_INPUT, + output_schema=_SCHEMA_STREAMING_TRAITS_WITH_MEDIA_TYPE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TestConfig: + """Dataclass for TestConfig structure.""" + + timeout: int | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_CONFIG, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.timeout is not None: + serializer.write_integer( + _SCHEMA_TEST_CONFIG.members["timeout"], self.timeout + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["timeout"] = de.read_integer( + _SCHEMA_TEST_CONFIG.members["timeout"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TEST_CONFIG, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class TestBodyStructureInput: + """Dataclass for TestBodyStructureInput structure.""" + + test_id: str | None = None + + test_config: TestConfig | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_BODY_STRUCTURE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_BODY_STRUCTURE_INPUT.members["testId"], self.test_id + ) + + if self.test_config is not None: + serializer.write_struct( + _SCHEMA_TEST_BODY_STRUCTURE_INPUT.members["testConfig"], + self.test_config, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_BODY_STRUCTURE_INPUT.members["testId"] + ) + + case 1: + kwargs["test_config"] = TestConfig.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TEST_BODY_STRUCTURE_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class TestBodyStructureOutput: + """Dataclass for TestBodyStructureOutput structure.""" + + test_id: str | None = None + + test_config: TestConfig | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_BODY_STRUCTURE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_BODY_STRUCTURE_OUTPUT.members["testId"], self.test_id + ) + + if self.test_config is not None: + serializer.write_struct( + _SCHEMA_TEST_BODY_STRUCTURE_OUTPUT.members["testConfig"], + self.test_config, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_BODY_STRUCTURE_OUTPUT.members["testId"] + ) + + case 1: + kwargs["test_config"] = TestConfig.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TEST_BODY_STRUCTURE_OUTPUT, consumer=_consumer) + return kwargs + + +TEST_BODY_STRUCTURE = APIOperation( + input=TestBodyStructureInput, + output=TestBodyStructureOutput, + schema=_SCHEMA_TEST_BODY_STRUCTURE, + input_schema=_SCHEMA_TEST_BODY_STRUCTURE_INPUT, + output_schema=_SCHEMA_TEST_BODY_STRUCTURE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TestGetNoInputNoPayloadInput: + """Dataclass for TestGetNoInputNoPayloadInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class TestGetNoInputNoPayloadOutput: + """Dataclass for TestGetNoInputNoPayloadOutput structure.""" + + test_id: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_OUTPUT.members["testId"], + self.test_id, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_OUTPUT.members["testId"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_OUTPUT, consumer=_consumer + ) + return kwargs + + +TEST_GET_NO_INPUT_NO_PAYLOAD = APIOperation( + input=TestGetNoInputNoPayloadInput, + output=TestGetNoInputNoPayloadOutput, + schema=_SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD, + input_schema=_SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_INPUT, + output_schema=_SCHEMA_TEST_GET_NO_INPUT_NO_PAYLOAD_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TestGetNoPayloadInput: + """Dataclass for TestGetNoPayloadInput structure.""" + + test_id: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_GET_NO_PAYLOAD_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_GET_NO_PAYLOAD_INPUT.members["testId"], self.test_id + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_GET_NO_PAYLOAD_INPUT.members["testId"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TEST_GET_NO_PAYLOAD_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class TestGetNoPayloadOutput: + """Dataclass for TestGetNoPayloadOutput structure.""" + + test_id: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_GET_NO_PAYLOAD_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_GET_NO_PAYLOAD_OUTPUT.members["testId"], self.test_id + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_GET_NO_PAYLOAD_OUTPUT.members["testId"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TEST_GET_NO_PAYLOAD_OUTPUT, consumer=_consumer) + return kwargs + + +TEST_GET_NO_PAYLOAD = APIOperation( + input=TestGetNoPayloadInput, + output=TestGetNoPayloadOutput, + schema=_SCHEMA_TEST_GET_NO_PAYLOAD, + input_schema=_SCHEMA_TEST_GET_NO_PAYLOAD_INPUT, + output_schema=_SCHEMA_TEST_GET_NO_PAYLOAD_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TestPayloadBlobInput: + """Dataclass for TestPayloadBlobInput structure.""" + + content_type: str | None = None + + data: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_PAYLOAD_BLOB_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.content_type is not None: + serializer.write_string( + _SCHEMA_TEST_PAYLOAD_BLOB_INPUT.members["contentType"], + self.content_type, + ) + + if self.data is not None: + serializer.write_blob( + _SCHEMA_TEST_PAYLOAD_BLOB_INPUT.members["data"], self.data + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["content_type"] = de.read_string( + _SCHEMA_TEST_PAYLOAD_BLOB_INPUT.members["contentType"] + ) + + case 1: + kwargs["data"] = de.read_blob( + _SCHEMA_TEST_PAYLOAD_BLOB_INPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TEST_PAYLOAD_BLOB_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class TestPayloadBlobOutput: + """Dataclass for TestPayloadBlobOutput structure.""" + + content_type: str | None = None + + data: bytes | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_PAYLOAD_BLOB_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.content_type is not None: + serializer.write_string( + _SCHEMA_TEST_PAYLOAD_BLOB_OUTPUT.members["contentType"], + self.content_type, + ) + + if self.data is not None: + serializer.write_blob( + _SCHEMA_TEST_PAYLOAD_BLOB_OUTPUT.members["data"], self.data + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["content_type"] = de.read_string( + _SCHEMA_TEST_PAYLOAD_BLOB_OUTPUT.members["contentType"] + ) + + case 1: + kwargs["data"] = de.read_blob( + _SCHEMA_TEST_PAYLOAD_BLOB_OUTPUT.members["data"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TEST_PAYLOAD_BLOB_OUTPUT, consumer=_consumer) + return kwargs + + +TEST_PAYLOAD_BLOB = APIOperation( + input=TestPayloadBlobInput, + output=TestPayloadBlobOutput, + schema=_SCHEMA_TEST_PAYLOAD_BLOB, + input_schema=_SCHEMA_TEST_PAYLOAD_BLOB_INPUT, + output_schema=_SCHEMA_TEST_PAYLOAD_BLOB_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TestPayloadStructureInput: + """Dataclass for TestPayloadStructureInput structure.""" + + test_id: str | None = None + + payload_config: PayloadConfig | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_PAYLOAD_STRUCTURE_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_PAYLOAD_STRUCTURE_INPUT.members["testId"], self.test_id + ) + + if self.payload_config is not None: + serializer.write_struct( + _SCHEMA_TEST_PAYLOAD_STRUCTURE_INPUT.members["payloadConfig"], + self.payload_config, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_PAYLOAD_STRUCTURE_INPUT.members["testId"] + ) + + case 1: + kwargs["payload_config"] = PayloadConfig.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_TEST_PAYLOAD_STRUCTURE_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class TestPayloadStructureOutput: + """Dataclass for TestPayloadStructureOutput structure.""" + + test_id: str | None = None + + payload_config: PayloadConfig | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_PAYLOAD_STRUCTURE_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_PAYLOAD_STRUCTURE_OUTPUT.members["testId"], self.test_id + ) + + if self.payload_config is not None: + serializer.write_struct( + _SCHEMA_TEST_PAYLOAD_STRUCTURE_OUTPUT.members["payloadConfig"], + self.payload_config, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_PAYLOAD_STRUCTURE_OUTPUT.members["testId"] + ) + + case 1: + kwargs["payload_config"] = PayloadConfig.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_TEST_PAYLOAD_STRUCTURE_OUTPUT, consumer=_consumer + ) + return kwargs + + +TEST_PAYLOAD_STRUCTURE = APIOperation( + input=TestPayloadStructureInput, + output=TestPayloadStructureOutput, + schema=_SCHEMA_TEST_PAYLOAD_STRUCTURE, + input_schema=_SCHEMA_TEST_PAYLOAD_STRUCTURE_INPUT, + output_schema=_SCHEMA_TEST_PAYLOAD_STRUCTURE_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TestPostNoInputNoPayloadInput: + """Dataclass for TestPostNoInputNoPayloadInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class TestPostNoInputNoPayloadOutput: + """Dataclass for TestPostNoInputNoPayloadOutput structure.""" + + test_id: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_OUTPUT.members["testId"], + self.test_id, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_OUTPUT.members["testId"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_OUTPUT, consumer=_consumer + ) + return kwargs + + +TEST_POST_NO_INPUT_NO_PAYLOAD = APIOperation( + input=TestPostNoInputNoPayloadInput, + output=TestPostNoInputNoPayloadOutput, + schema=_SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD, + input_schema=_SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_INPUT, + output_schema=_SCHEMA_TEST_POST_NO_INPUT_NO_PAYLOAD_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TestPostNoPayloadInput: + """Dataclass for TestPostNoPayloadInput structure.""" + + test_id: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_POST_NO_PAYLOAD_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_POST_NO_PAYLOAD_INPUT.members["testId"], self.test_id + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_POST_NO_PAYLOAD_INPUT.members["testId"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_TEST_POST_NO_PAYLOAD_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class TestPostNoPayloadOutput: + """Dataclass for TestPostNoPayloadOutput structure.""" + + test_id: str | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TEST_POST_NO_PAYLOAD_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.test_id is not None: + serializer.write_string( + _SCHEMA_TEST_POST_NO_PAYLOAD_OUTPUT.members["testId"], self.test_id + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["test_id"] = de.read_string( + _SCHEMA_TEST_POST_NO_PAYLOAD_OUTPUT.members["testId"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_TEST_POST_NO_PAYLOAD_OUTPUT, consumer=_consumer + ) + return kwargs + + +TEST_POST_NO_PAYLOAD = APIOperation( + input=TestPostNoPayloadInput, + output=TestPostNoPayloadOutput, + schema=_SCHEMA_TEST_POST_NO_PAYLOAD, + input_schema=_SCHEMA_TEST_POST_NO_PAYLOAD_INPUT, + output_schema=_SCHEMA_TEST_POST_NO_PAYLOAD_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class TimestampFormatHeadersInput: + """Dataclass for TimestampFormatHeadersInput structure.""" + + member_epoch_seconds: datetime | None = None + + member_http_date: datetime | None = None + + member_date_time: datetime | None = None + + default_format: datetime | None = None + + target_epoch_seconds: datetime | None = None + + target_http_date: datetime | None = None + + target_date_time: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.member_epoch_seconds is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["memberEpochSeconds"], + self.member_epoch_seconds, + ) + + if self.member_http_date is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["memberHttpDate"], + self.member_http_date, + ) + + if self.member_date_time is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["memberDateTime"], + self.member_date_time, + ) + + if self.default_format is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["defaultFormat"], + self.default_format, + ) + + if self.target_epoch_seconds is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["targetEpochSeconds"], + self.target_epoch_seconds, + ) + + if self.target_http_date is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["targetHttpDate"], + self.target_http_date, + ) + + if self.target_date_time is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["targetDateTime"], + self.target_date_time, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["member_epoch_seconds"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members[ + "memberEpochSeconds" + ] + ) + + case 1: + kwargs["member_http_date"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["memberHttpDate"] + ) + + case 2: + kwargs["member_date_time"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["memberDateTime"] + ) + + case 3: + kwargs["default_format"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["defaultFormat"] + ) + + case 4: + kwargs["target_epoch_seconds"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members[ + "targetEpochSeconds" + ] + ) + + case 5: + kwargs["target_http_date"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["targetHttpDate"] + ) + + case 6: + kwargs["target_date_time"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT.members["targetDateTime"] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class TimestampFormatHeadersOutput: + """Dataclass for TimestampFormatHeadersOutput structure.""" + + member_epoch_seconds: datetime | None = None + + member_http_date: datetime | None = None + + member_date_time: datetime | None = None + + default_format: datetime | None = None + + target_epoch_seconds: datetime | None = None + + target_http_date: datetime | None = None + + target_date_time: datetime | None = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.member_epoch_seconds is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members["memberEpochSeconds"], + self.member_epoch_seconds, + ) + + if self.member_http_date is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members["memberHttpDate"], + self.member_http_date, + ) + + if self.member_date_time is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members["memberDateTime"], + self.member_date_time, + ) + + if self.default_format is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members["defaultFormat"], + self.default_format, + ) + + if self.target_epoch_seconds is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members["targetEpochSeconds"], + self.target_epoch_seconds, + ) + + if self.target_http_date is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members["targetHttpDate"], + self.target_http_date, + ) + + if self.target_date_time is not None: + serializer.write_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members["targetDateTime"], + self.target_date_time, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["member_epoch_seconds"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members[ + "memberEpochSeconds" + ] + ) + + case 1: + kwargs["member_http_date"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members[ + "memberHttpDate" + ] + ) + + case 2: + kwargs["member_date_time"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members[ + "memberDateTime" + ] + ) + + case 3: + kwargs["default_format"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members["defaultFormat"] + ) + + case 4: + kwargs["target_epoch_seconds"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members[ + "targetEpochSeconds" + ] + ) + + case 5: + kwargs["target_http_date"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members[ + "targetHttpDate" + ] + ) + + case 6: + kwargs["target_date_time"] = de.read_timestamp( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT.members[ + "targetDateTime" + ] + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT, consumer=_consumer + ) + return kwargs + + +TIMESTAMP_FORMAT_HEADERS = APIOperation( + input=TimestampFormatHeadersInput, + output=TimestampFormatHeadersOutput, + schema=_SCHEMA_TIMESTAMP_FORMAT_HEADERS, + input_schema=_SCHEMA_TIMESTAMP_FORMAT_HEADERS_INPUT, + output_schema=_SCHEMA_TIMESTAMP_FORMAT_HEADERS_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class UnitInputAndOutputInput: + """Dataclass for UnitInputAndOutputInput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_UNIT_INPUT_AND_OUTPUT_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_UNIT_INPUT_AND_OUTPUT_INPUT, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class UnitInputAndOutputOutput: + """Dataclass for UnitInputAndOutputOutput structure.""" + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_UNIT_INPUT_AND_OUTPUT_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + pass + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_UNIT_INPUT_AND_OUTPUT_OUTPUT, consumer=_consumer + ) + return kwargs + + +UNIT_INPUT_AND_OUTPUT = APIOperation( + input=UnitInputAndOutputInput, + output=UnitInputAndOutputOutput, + schema=_SCHEMA_UNIT_INPUT_AND_OUTPUT, + input_schema=_SCHEMA_UNIT_INPUT_AND_OUTPUT_INPUT, + output_schema=_SCHEMA_UNIT_INPUT_AND_OUTPUT_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) + + +@dataclass(kw_only=True) +class RecursiveShapesInputOutputNested1: + """Dataclass for RecursiveShapesInputOutputNested1 structure.""" + + foo: str | None = None + + nested: "RecursiveShapesInputOutputNested2 | None" = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.foo is not None: + serializer.write_string( + _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1.members["foo"], self.foo + ) + + if self.nested is not None: + serializer.write_struct( + _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1.members["nested"], + self.nested, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["foo"] = de.read_string( + _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1.members["foo"] + ) + + case 1: + kwargs["nested"] = RecursiveShapesInputOutputNested2.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED1, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class RecursiveShapesInputOutputNested2: + """Dataclass for RecursiveShapesInputOutputNested2 structure.""" + + bar: str | None = None + + recursive_member: "RecursiveShapesInputOutputNested1 | None" = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED2, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.bar is not None: + serializer.write_string( + _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED2.members["bar"], self.bar + ) + + if self.recursive_member is not None: + serializer.write_struct( + _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED2.members[ + "recursiveMember" + ], + self.recursive_member, + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["bar"] = de.read_string( + _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED2.members["bar"] + ) + + case 1: + kwargs["recursive_member"] = ( + RecursiveShapesInputOutputNested1.deserialize(de) + ) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct( + _SCHEMA_RECURSIVE_SHAPES_INPUT_OUTPUT_NESTED2, consumer=_consumer + ) + return kwargs + + +@dataclass(kw_only=True) +class RecursiveShapesInput: + """Dataclass for RecursiveShapesInput structure.""" + + nested: "RecursiveShapesInputOutputNested1 | None" = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RECURSIVE_SHAPES_INPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.nested is not None: + serializer.write_struct( + _SCHEMA_RECURSIVE_SHAPES_INPUT.members["nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["nested"] = RecursiveShapesInputOutputNested1.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_RECURSIVE_SHAPES_INPUT, consumer=_consumer) + return kwargs + + +@dataclass(kw_only=True) +class RecursiveShapesOutput: + """Dataclass for RecursiveShapesOutput structure.""" + + nested: "RecursiveShapesInputOutputNested1 | None" = None + + def serialize(self, serializer: ShapeSerializer): + serializer.write_struct(_SCHEMA_RECURSIVE_SHAPES_OUTPUT, self) + + def serialize_members(self, serializer: ShapeSerializer): + if self.nested is not None: + serializer.write_struct( + _SCHEMA_RECURSIVE_SHAPES_OUTPUT.members["nested"], self.nested + ) + + @classmethod + def deserialize(cls, deserializer: ShapeDeserializer) -> Self: + return cls(**cls.deserialize_kwargs(deserializer)) + + @classmethod + def deserialize_kwargs(cls, deserializer: ShapeDeserializer) -> dict[str, Any]: + kwargs: dict[str, Any] = {} + + def _consumer(schema: Schema, de: ShapeDeserializer) -> None: + match schema.expect_member_index(): + case 0: + kwargs["nested"] = RecursiveShapesInputOutputNested1.deserialize(de) + + case _: + logger.debug("Unexpected member schema: %s", schema) + + deserializer.read_struct(_SCHEMA_RECURSIVE_SHAPES_OUTPUT, consumer=_consumer) + return kwargs + + +RECURSIVE_SHAPES = APIOperation( + input=RecursiveShapesInput, + output=RecursiveShapesOutput, + schema=_SCHEMA_RECURSIVE_SHAPES, + input_schema=_SCHEMA_RECURSIVE_SHAPES_INPUT, + output_schema=_SCHEMA_RECURSIVE_SHAPES_OUTPUT, + error_registry=TypeRegistry({}), + effective_auth_schemes=[ShapeID("aws.auth#sigv4")], + error_schemas=[], +) diff --git a/codegen-output/rest-json-1/src/restjson/user_agent.py b/codegen-output/rest-json-1/src/restjson/user_agent.py new file mode 100644 index 000000000..9cd40222d --- /dev/null +++ b/codegen-output/rest-json-1/src/restjson/user_agent.py @@ -0,0 +1,17 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from smithy_aws_core.interceptors.user_agent import UserAgentInterceptor + +from . import __version__ +from .config import AsyncRestJsonProtocolConfig + + +def aws_user_agent_plugin(config: AsyncRestJsonProtocolConfig): + config.interceptors.append( + UserAgentInterceptor( + ua_suffix=config.user_agent_extra, + ua_app_id=config.sdk_ua_app_id, + sdk_version=__version__, + service_id="Rest_Json_Protocol", + ) + ) diff --git a/codegen-output/rest-json-1/tests/__init__.py b/codegen-output/rest-json-1/tests/__init__.py new file mode 100644 index 000000000..247be3e3d --- /dev/null +++ b/codegen-output/rest-json-1/tests/__init__.py @@ -0,0 +1 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. diff --git a/codegen-output/rest-json-1/tests/test_restjson_protocol.py b/codegen-output/rest-json-1/tests/test_restjson_protocol.py new file mode 100644 index 000000000..b3ee6fd67 --- /dev/null +++ b/codegen-output/rest-json-1/tests/test_restjson_protocol.py @@ -0,0 +1,14303 @@ +# Code generated by smithy-python-codegen DO NOT EDIT. + +from datetime import datetime, timezone +import json +from urllib.parse import parse_qsl + +from pytest import fail, mark, raises +from smithy_aws_core.identity import StaticCredentialsResolver +from smithy_core.aio.interfaces import AsyncByteStream +from smithy_core.aio.retries import SimpleRetryStrategy +from smithy_core.aio.types import AsyncBytesReader +from smithy_core.aio.utils import async_list +from smithy_core.documents import Document +from smithy_http import tuples_to_fields +from smithy_http.aio import HTTPResponse as _smithy_http_aio_HTTPResponse +from smithy_http.aio.interfaces import ( + HTTPRequest, + HTTPResponse as _smithy_http_aio_interfaces_HTTPResponse, +) +from smithy_http.interfaces import HTTPClientConfiguration, HTTPRequestConfiguration + +from restjson.client import AsyncRestJsonProtocolClient +from restjson.config import AsyncRestJsonProtocolConfig +from restjson.models import ( + AllQueryStringTypesInput, + ClientOptionalDefaults, + ConstantAndVariableQueryStringInput, + ConstantQueryStringInput, + DatetimeOffsetsInput, + DatetimeOffsetsOutput, + Defaults, + Dialog, + DocumentTypeAsMapValueInput, + DocumentTypeAsMapValueOutput, + DocumentTypeAsPayloadInput, + DocumentTypeAsPayloadOutput, + DocumentTypeInput, + DocumentTypeOutput, + EmptyInputAndEmptyOutputInput, + EmptyInputAndEmptyOutputOutput, + EndpointOperationInput, + EndpointWithHostLabelOperationInput, + Farewell, + FractionalSecondsInput, + FractionalSecondsOutput, + GreetingStruct, + GreetingWithErrorsInput, + GreetingWithErrorsOutput, + HostWithPathOperationInput, + HttpChecksumRequiredInput, + HttpEmptyPrefixHeadersInput, + HttpEmptyPrefixHeadersOutput, + HttpEnumPayloadInput, + HttpEnumPayloadOutput, + HttpPayloadTraitsInput, + HttpPayloadTraitsOutput, + HttpPayloadTraitsWithMediaTypeInput, + HttpPayloadTraitsWithMediaTypeOutput, + HttpPayloadWithStructureInput, + HttpPayloadWithStructureOutput, + HttpPayloadWithUnionInput, + HttpPayloadWithUnionOutput, + HttpPrefixHeadersInResponseInput, + HttpPrefixHeadersInResponseOutput, + HttpPrefixHeadersInput, + HttpPrefixHeadersOutput, + HttpQueryParamsOnlyOperationInput, + HttpRequestWithFloatLabelsInput, + HttpRequestWithGreedyLabelInPathInput, + HttpRequestWithLabelsAndTimestampFormatInput, + HttpRequestWithLabelsInput, + HttpRequestWithRegexLiteralInput, + HttpResponseCodeInput, + HttpResponseCodeOutput, + HttpStringPayloadInput, + HttpStringPayloadOutput, + IgnoreQueryParamsInResponseInput, + IgnoreQueryParamsInResponseOutput, + InputAndOutputWithHeadersInput, + InputAndOutputWithHeadersOutput, + JsonBlobsInput, + JsonBlobsOutput, + JsonEnumsInput, + JsonEnumsOutput, + JsonIntEnumsInput, + JsonIntEnumsOutput, + JsonListsInput, + JsonListsOutput, + JsonMapsInput, + JsonMapsOutput, + JsonTimestampsInput, + JsonTimestampsOutput, + JsonUnionsInput, + JsonUnionsOutput, + MediaTypeHeaderInput, + MediaTypeHeaderOutput, + MyUnionBlobValue, + MyUnionBooleanValue, + MyUnionEnumValue, + MyUnionListValue, + MyUnionMapValue, + MyUnionNumberValue, + MyUnionRenamedStructureValue, + MyUnionStringValue, + MyUnionStructureValue, + MyUnionTimestampValue, + MyUnionUnionValue, + NestedPayload, + NestedUnionStringValue, + NoInputAndNoOutputInput, + NoInputAndNoOutputOutput, + NoInputAndOutputInput, + NoInputAndOutputOutput, + NullAndEmptyHeadersClientInput, + OmitsNullSerializesEmptyStringInput, + OmitsSerializingEmptyListsInput, + OperationWithDefaultsInput, + OperationWithDefaultsOutput, + OperationWithNestedStructureInput, + OperationWithNestedStructureOutput, + PayloadConfig, + PlayerActionQuit, + PostPlayerActionInput, + PostPlayerActionOutput, + PostUnionWithJsonNameInput, + PostUnionWithJsonNameOutput, + PutWithContentEncodingInput, + QueryIdempotencyTokenAutoFillInput, + QueryParamsAsStringListMapInput, + QueryPrecedenceInput, + RecursiveShapesInput, + RecursiveShapesInputOutputNested1, + RecursiveShapesInputOutputNested2, + RecursiveShapesOutput, + RenamedGreeting, + ServiceError, + SimpleScalarPropertiesInput, + SimpleScalarPropertiesOutput, + SparseJsonListsInput, + SparseJsonListsOutput, + SparseJsonMapsInput, + SparseJsonMapsOutput, + StreamingTraitsInput, + StreamingTraitsOutput, + StreamingTraitsRequireLengthInput, + StreamingTraitsWithMediaTypeInput, + StreamingTraitsWithMediaTypeOutput, + StructureListMember, + TestBodyStructureInput, + TestConfig, + TestGetNoInputNoPayloadInput, + TestGetNoPayloadInput, + TestPayloadBlobInput, + TestPayloadStructureInput, + TestPostNoInputNoPayloadInput, + TestPostNoPayloadInput, + TimestampFormatHeadersInput, + TimestampFormatHeadersOutput, + TopLevel, + UnionPayloadGreeting, + UnionWithJsonNameBar, + UnionWithJsonNameBaz, + UnionWithJsonNameFoo, + Unit, + UnitInputAndOutputInput, + UnitInputAndOutputOutput, +) + + +async def test_rest_json_all_query_string_types_request_all_query_string_types() -> ( + None +): + """Serializes query string parameters with all supported types""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = AllQueryStringTypesInput( + query_string="Hello there", + query_string_list=["a", "b", "c"], + query_string_set=["a", "b", "c"], + query_byte=1, + query_short=2, + query_integer=3, + query_integer_list=[1, 2, 3], + query_integer_set=[1, 2, 3], + query_long=4, + query_float=float(1.1), + query_double=float(1.1), + query_double_list=[float(1.1), float(2.1), float(3.1)], + query_boolean=True, + query_boolean_list=[True, False, True], + query_timestamp=datetime(1970, 1, 1, 0, 0, 1, 0, timezone.utc), + query_timestamp_list=[ + datetime(1970, 1, 1, 0, 0, 1, 0, timezone.utc), + datetime(1970, 1, 1, 0, 0, 2, 0, timezone.utc), + datetime(1970, 1, 1, 0, 0, 3, 0, timezone.utc), + ], + query_enum="Foo", + query_enum_list=["Foo", "Baz", "Bar"], + query_integer_enum=1, + query_integer_enum_list=[1, 2, 3], + query_params_map_of_string_list={ + "String": ["Hello there"], + "StringList": ["a", "b", "c"], + "StringSet": ["a", "b", "c"], + "Byte": ["1"], + "Short": ["2"], + "Integer": ["3"], + "IntegerList": ["1", "2", "3"], + "IntegerSet": ["1", "2", "3"], + "Long": ["4"], + "Float": ["1.1"], + "Double": ["1.1"], + "DoubleList": ["1.1", "2.1", "3.1"], + "Boolean": ["true"], + "BooleanList": ["true", "false", "true"], + "Timestamp": ["1970-01-01T00:00:01Z"], + "TimestampList": [ + "1970-01-01T00:00:01Z", + "1970-01-01T00:00:02Z", + "1970-01-01T00:00:03Z", + ], + "Enum": ["Foo"], + "EnumList": ["Foo", "Baz", "Bar"], + "IntegerEnum": ["1"], + "IntegerEnumList": ["1", "2", "3"], + }, + ) + + try: + await client.all_query_string_types(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/AllQueryStringTypesInput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [ + "String=Hello%20there", + "StringList=a", + "StringList=b", + "StringList=c", + "StringSet=a", + "StringSet=b", + "StringSet=c", + "Byte=1", + "Short=2", + "Integer=3", + "IntegerList=1", + "IntegerList=2", + "IntegerList=3", + "IntegerSet=1", + "IntegerSet=2", + "IntegerSet=3", + "Long=4", + "Float=1.1", + "Double=1.1", + "DoubleList=1.1", + "DoubleList=2.1", + "DoubleList=3.1", + "Boolean=true", + "BooleanList=true", + "BooleanList=false", + "BooleanList=true", + "Timestamp=1970-01-01T00%3A00%3A01Z", + "TimestampList=1970-01-01T00%3A00%3A01Z", + "TimestampList=1970-01-01T00%3A00%3A02Z", + "TimestampList=1970-01-01T00%3A00%3A03Z", + "Enum=Foo", + "EnumList=Foo", + "EnumList=Baz", + "EnumList=Bar", + "IntegerEnum=1", + "IntegerEnumList=1", + "IntegerEnumList=2", + "IntegerEnumList=3", + ] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_query_string_map_request_all_query_string_types() -> None: + """Handles query string maps""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = AllQueryStringTypesInput( + query_params_map_of_string_list={ + "QueryParamsStringKeyA": ["Foo"], + "QueryParamsStringKeyB": ["Bar"], + } + ) + + try: + await client.all_query_string_types(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/AllQueryStringTypesInput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [ + "QueryParamsStringKeyA=Foo", + "QueryParamsStringKeyB=Bar", + ] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_query_string_escaping_request_all_query_string_types() -> None: + """Handles escaping all required characters in the query string.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = AllQueryStringTypesInput( + query_string=" %:/?#[]@!$&'()*+,;=😹", + query_params_map_of_string_list={"String": [" %:/?#[]@!$&'()*+,;=😹"]}, + ) + + try: + await client.all_query_string_types(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/AllQueryStringTypesInput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [ + "String=%20%25%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D%F0%9F%98%B9" + ] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_na_n_float_query_values_request_all_query_string_types() -> ( + None +): + """Supports handling NaN float query values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = AllQueryStringTypesInput( + query_float=float("nan"), + query_double=float("nan"), + query_params_map_of_string_list={"Float": ["NaN"], "Double": ["NaN"]}, + ) + + try: + await client.all_query_string_types(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/AllQueryStringTypesInput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["Float=NaN", "Double=NaN"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_infinity_float_query_values_request_all_query_string_types() -> ( + None +): + """Supports handling Infinity float query values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = AllQueryStringTypesInput( + query_float=float("inf"), + query_double=float("inf"), + query_params_map_of_string_list={"Float": ["Infinity"], "Double": ["Infinity"]}, + ) + + try: + await client.all_query_string_types(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/AllQueryStringTypesInput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["Float=Infinity", "Double=Infinity"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_negative_infinity_float_query_values_request_all_query_string_types() -> ( + None +): + """Supports handling -Infinity float query values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = AllQueryStringTypesInput( + query_float=float("-inf"), + query_double=float("-inf"), + query_params_map_of_string_list={ + "Float": ["-Infinity"], + "Double": ["-Infinity"], + }, + ) + + try: + await client.all_query_string_types(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/AllQueryStringTypesInput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["Float=-Infinity", "Double=-Infinity"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_zero_and_false_query_values_request_all_query_string_types() -> ( + None +): + """Query values of 0 and false are serialized""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = AllQueryStringTypesInput( + query_integer=0, + query_boolean=False, + query_params_map_of_string_list={"Integer": ["0"], "Boolean": ["false"]}, + ) + + try: + await client.all_query_string_types(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/AllQueryStringTypesInput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["Integer=0", "Boolean=false"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_constant_and_variable_query_string_missing_one_value_request_constant_and_variable_query_string() -> ( + None +): + """Mixes constant and variable query string parameters""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = ConstantAndVariableQueryStringInput(baz="bam") + + try: + await client.constant_and_variable_query_string(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/ConstantAndVariableQueryString" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["foo=bar", "baz=bam"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set(["maybeset"]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_constant_and_variable_query_string_all_values_request_constant_and_variable_query_string() -> ( + None +): + """Mixes constant and variable query string parameters""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = ConstantAndVariableQueryStringInput(baz="bam", maybe_set="yes") + + try: + await client.constant_and_variable_query_string(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/ConstantAndVariableQueryString" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["foo=bar", "baz=bam", "maybeSet=yes"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_constant_query_string_request_constant_query_string() -> None: + """Includes constant query string parameters""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = ConstantQueryStringInput(hello="hi") + + try: + await client.constant_query_string(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/ConstantQueryString/hi" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["foo=bar", "hello"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_date_time_with_negative_offset_response_datetime_offsets() -> ( + None +): + """ + Ensures that clients can correctly parse datetime (timestamps) with + offsets + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[], + body=b' {\n "datetime": "2019-12-16T22:48:18-01:00"\n }\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DatetimeOffsetsInput() + + try: + actual = await client.datetime_offsets(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DatetimeOffsetsOutput( + datetime_=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_rest_json_date_time_with_positive_offset_response_datetime_offsets() -> ( + None +): + """ + Ensures that clients can correctly parse datetime (timestamps) with + offsets + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[], + body=b' {\n "datetime": "2019-12-17T00:48:18+01:00"\n }\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DatetimeOffsetsInput() + + try: + actual = await client.datetime_offsets(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DatetimeOffsetsOutput( + datetime_=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_document_type_input_with_object_request_document_type() -> None: + """ + Serializes document types as part of the JSON request payload with no + escaping. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput( + string_value="string", document_value=Document({"foo": "bar"}) + ) + + try: + await client.document_type(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/DocumentType" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "stringValue": "string",\n "documentValue": {\n "foo": "bar"\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_document_input_with_string_request_document_type() -> None: + """Serializes document types using a string.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput(string_value="string", document_value=Document("hello")) + + try: + await client.document_type(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/DocumentType" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "stringValue": "string",\n "documentValue": "hello"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_document_input_with_number_request_document_type() -> None: + """Serializes document types using a number.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput(string_value="string", document_value=Document(10)) + + try: + await client.document_type(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/DocumentType" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "stringValue": "string",\n "documentValue": 10\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_document_input_with_boolean_request_document_type() -> None: + """Serializes document types using a boolean.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput(string_value="string", document_value=Document(True)) + + try: + await client.document_type(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/DocumentType" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "stringValue": "string",\n "documentValue": true\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_document_input_with_list_request_document_type() -> None: + """Serializes document types using a list.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput( + string_value="string", + document_value=Document([True, "hi", [1, 2], {"foo": {"baz": [3, 4]}}]), + ) + + try: + await client.document_type(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/DocumentType" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "stringValue": "string",\n "documentValue": [\n true,\n "hi",\n [\n 1,\n 2\n ],\n {\n "foo": {\n "baz": [\n 3,\n 4\n ]\n }\n }\n ]\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_document_output_response_document_type() -> None: + """ + Serializes documents as part of the JSON response payload with no + escaping. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "stringValue": "string",\n "documentValue": {\n "foo": "bar"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput() + + try: + actual = await client.document_type(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DocumentTypeOutput( + string_value="string", document_value=Document({"foo": "bar"}) + ) + + assert actual == expected + + +async def test_document_output_string_response_document_type() -> None: + """Document types can be JSON scalars too.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "stringValue": "string",\n "documentValue": "hello"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput() + + try: + actual = await client.document_type(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DocumentTypeOutput( + string_value="string", document_value=Document("hello") + ) + + assert actual == expected + + +async def test_document_output_number_response_document_type() -> None: + """Document types can be JSON scalars too.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "stringValue": "string",\n "documentValue": 10\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput() + + try: + actual = await client.document_type(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DocumentTypeOutput( + string_value="string", document_value=Document(10) + ) + + assert actual == expected + + +async def test_document_output_boolean_response_document_type() -> None: + """Document types can be JSON scalars too.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "stringValue": "string",\n "documentValue": false\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput() + + try: + actual = await client.document_type(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DocumentTypeOutput( + string_value="string", document_value=Document(False) + ) + + assert actual == expected + + +async def test_document_output_array_response_document_type() -> None: + """Document types can be JSON arrays.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "stringValue": "string",\n "documentValue": [\n true,\n false\n ]\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeInput() + + try: + actual = await client.document_type(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DocumentTypeOutput( + string_value="string", document_value=Document([True, False]) + ) + + assert actual == expected + + +async def test_document_type_as_map_value_input_request_document_type_as_map_value() -> ( + None +): + """Serializes a map that uses documents as the value.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeAsMapValueInput( + doc_valued_map={ + "foo": Document({"f": 1, "o": 2}), + "bar": Document(["b", "a", "r"]), + "baz": Document("BAZ"), + } + ) + + try: + await client.document_type_as_map_value(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/DocumentTypeAsMapValue" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "docValuedMap": {\n "foo": { "f": 1, "o": 2 },\n "bar": [ "b", "a", "r" ],\n "baz": "BAZ"\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_document_type_as_map_value_output_response_document_type_as_map_value() -> ( + None +): + """Serializes a map that uses documents as the value.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "docValuedMap": {\n "foo": { "f": 1, "o": 2 },\n "bar": [ "b", "a", "r" ],\n "baz": "BAZ"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeAsMapValueInput() + + try: + actual = await client.document_type_as_map_value(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DocumentTypeAsMapValueOutput( + doc_valued_map={ + "foo": Document({"f": 1, "o": 2}), + "bar": Document(["b", "a", "r"]), + "baz": Document("BAZ"), + } + ) + + assert actual == expected + + +async def test_document_type_as_payload_input_request_document_type_as_payload() -> ( + None +): + """Serializes a document as the target of the httpPayload trait.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeAsPayloadInput(document_value=Document({"foo": "bar"})) + + try: + await client.document_type_as_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/DocumentTypeAsPayload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "foo": "bar"\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_document_type_as_payload_input_string_request_document_type_as_payload() -> ( + None +): + """ + Serializes a document as the target of the httpPayload trait using a + string. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeAsPayloadInput(document_value=Document("hello")) + + try: + await client.document_type_as_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/DocumentTypeAsPayload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'"hello"' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_document_type_as_payload_output_response_document_type_as_payload() -> ( + None +): + """Serializes a document as the target of the httpPayload trait.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "foo": "bar"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeAsPayloadInput() + + try: + actual = await client.document_type_as_payload(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DocumentTypeAsPayloadOutput(document_value=Document({"foo": "bar"})) + + assert actual == expected + + +async def test_document_type_as_payload_output_string_response_document_type_as_payload() -> ( + None +): + """Serializes a document as a payload string.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'"hello"', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = DocumentTypeAsPayloadInput() + + try: + actual = await client.document_type_as_payload(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = DocumentTypeAsPayloadOutput(document_value=Document("hello")) + + assert actual == expected + + +async def test_rest_json_empty_input_and_empty_output_request_empty_input_and_empty_output() -> ( + None +): + """ + Clients should not serialize a JSON payload when no parameters are given + that are sent in the body. A service will tolerate clients that omit a + payload or that send a JSON object. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyInputAndEmptyOutputInput() + + try: + await client.empty_input_and_empty_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/EmptyInputAndEmptyOutput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_empty_input_and_empty_output_response_empty_input_and_empty_output() -> ( + None +): + """ + As of January 2021, server implementations are expected to respond with + a JSON object regardless of if the output parameters are empty. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("Content-Type", "application/json")], body=b"{}" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyInputAndEmptyOutputInput() + + try: + actual = await client.empty_input_and_empty_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = EmptyInputAndEmptyOutputOutput() + + assert actual == expected + + +async def test_rest_json_empty_input_and_empty_output_json_object_output_response_empty_input_and_empty_output() -> ( + None +): + """ + This test ensures that clients can gracefully handle situations where a + service omits a JSON payload entirely. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient(status=200, headers=[], body=b""), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EmptyInputAndEmptyOutputInput() + + try: + actual = await client.empty_input_and_empty_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = EmptyInputAndEmptyOutputOutput() + + assert actual == expected + + +@mark.xfail() +async def test_rest_json_endpoint_trait_request_endpoint_operation() -> None: + """ + Operations can prepend to the given host if they define the endpoint + trait. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EndpointOperationInput() + + try: + await client.endpoint_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/EndpointOperation" + assert actual.destination.host == "foo.example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_endpoint_trait_with_host_label_request_endpoint_with_host_label_operation() -> ( + None +): + """ + Operations can prepend to the given host if they define the endpoint + trait, and can use the host label trait to define further customization + based on user input. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = EndpointWithHostLabelOperationInput(label="bar") + + try: + await client.endpoint_with_host_label_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/EndpointWithHostLabelOperation" + assert actual.destination.host == "foo.bar.example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"label": "bar"}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_date_time_with_fractional_seconds_response_fractional_seconds() -> ( + None +): + """ + Ensures that clients can correctly parse datetime timestamps with + fractional seconds + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[], + body=b' {\n "datetime": "2000-01-02T20:34:56.123Z"\n }\n', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = FractionalSecondsInput() + + try: + actual = await client.fractional_seconds(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = FractionalSecondsOutput( + datetime_=datetime(2000, 1, 2, 20, 34, 56, 123000, timezone.utc) + ) + + assert actual == expected + + +async def test_rest_json_greeting_with_errors_response_greeting_with_errors() -> None: + """ + Ensures that operations with errors successfully know how to deserialize + a successful response. As of January 2021, server implementations are + expected to respond with a JSON object regardless of if the output + parameters are empty. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("X-Greeting", "Hello")], body=b"{}" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + actual = await client.greeting_with_errors(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = GreetingWithErrorsOutput(greeting="Hello") + + assert actual == expected + + +async def test_rest_json_greeting_with_errors_no_payload_response_greeting_with_errors() -> ( + None +): + """ + This test is similar to RestJsonGreetingWithErrors, but it ensures that + clients can gracefully deal with a server omitting a response payload. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("X-Greeting", "Hello")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + actual = await client.greeting_with_errors(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = GreetingWithErrorsOutput(greeting="Hello") + + assert actual == expected + + +async def test_rest_json_invalid_greeting_error_error_greeting_with_errors() -> None: + """Parses simple JSON errors""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=400, + headers=[ + ("Content-Type", "application/json"), + ("X-Amzn-Errortype", "InvalidGreeting"), + ], + body=b'{\n "Message": "Hi"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'InvalidGreeting' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "InvalidGreeting": + fail( + f"Expected 'InvalidGreeting' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_complex_error_with_no_message_error_greeting_with_errors() -> ( + None +): + """Serializes a complex error with no message member""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=403, + headers=[ + ("Content-Type", "application/json"), + ("X-Amzn-Errortype", "ComplexError"), + ("X-Header", "Header"), + ], + body=b'{\n "TopLevel": "Top level",\n "Nested": {\n "Fooooo": "bar"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'ComplexError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "ComplexError": + fail( + f"Expected 'ComplexError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_empty_complex_error_with_no_message_error_greeting_with_errors() -> ( + None +): + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=403, + headers=[ + ("Content-Type", "application/json"), + ("X-Amzn-Errortype", "ComplexError"), + ], + body=b"{}", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'ComplexError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "ComplexError": + fail( + f"Expected 'ComplexError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_using_x_amzn_error_type_error_greeting_with_errors() -> ( + None +): + """ + Serializes the X-Amzn-ErrorType header. For an example service, see + Amazon EKS. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, headers=[("X-Amzn-Errortype", "FooError")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_using_x_amzn_error_type_with_uri_error_greeting_with_errors() -> ( + None +): + """ + Some X-Amzn-Errortype headers contain URLs. Clients need to split the + URL on ':' and take only the first half of the string. For example, + 'ValidationException:http://internal.amazon.com/coral/com.amazon.coral.validate/' + is to be interpreted as 'ValidationException'. For an example service + see Amazon Polly. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[ + ( + "X-Amzn-Errortype", + "FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/", + ) + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_using_x_amzn_error_type_with_uri_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + X-Amzn-Errortype might contain a URL and a namespace. Client should + extract only the shape name. This is a pathalogical case that might not + actually happen in any deployed AWS service. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[ + ( + "X-Amzn-Errortype", + "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/", + ) + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_using_x_amzn_error_type_with_uri_and_different_namespace_error_greeting_with_errors() -> ( + None +): + """ + Because namespace and URL are ignored, an unrecognized namespace should + not make a difference. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[ + ( + "X-Amzn-Errortype", + "aws.different.namespace#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/", + ) + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_using_code_error_greeting_with_errors() -> None: + """ + This example uses the 'code' property in the output rather than + X-Amzn-Errortype. Some services do this though it's preferable to send + the X-Amzn-Errortype. Client implementations must first check for the + X-Amzn-Errortype and then check for a top-level 'code' property. For + example service see Amazon S3 Glacier. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/json")], + body=b'{\n "code": "FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_using_code_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using code, and it might contain a + namespace. Clients should just take the last part of the string after + '#'. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/json")], + body=b'{\n "code": "aws.protocoltests.restjson#FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_using_code_uri_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using code, and it might contain a + namespace. It also might contain a URI. Clients should just take the + last part of the string after '#' and before \":\". This is a + pathalogical case that might not occur in any deployed AWS service. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/json")], + body=b'{\n "code": "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_with_dunder_type_error_greeting_with_errors() -> ( + None +): + """Some services serialize errors using __type.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/json")], + body=b'{\n "__type": "FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_with_dunder_type_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using __type, and it might contain a + namespace. Clients should just take the last part of the string after + '#'. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/json")], + body=b'{\n "__type": "aws.protocoltests.restjson#FooError"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_with_dunder_type_uri_and_namespace_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using __type, and it might contain a + namespace. It also might contain a URI. Clients should just take the + last part of the string after '#' and before \":\". This is a + pathalogical case that might not occur in any deployed AWS service. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/json")], + body=b'{\n "__type": "aws.protocoltests.restjson#FooError:http://internal.amazon.com/coral/com.amazon.coral.validate/"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_foo_error_with_nested_type_property_error_greeting_with_errors() -> ( + None +): + """ + Some services serialize errors using __type, and if the response + includes additional shapes that belong to a different namespace + there'll be a nested __type property that must not be considered when + determining which error to be surfaced. For an example service see + Amazon DynamoDB. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=500, + headers=[("Content-Type", "application/json")], + body=b'{\n "__type": "aws.protocoltests.restjson#FooError",\n "ErrorDetails": [\n {\n "__type": "com.amazon.internal#ErrorDetails",\n "reason": "Some reason"\n }\n ]\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = GreetingWithErrorsInput() + + try: + await client.greeting_with_errors(input_) + fail("Expected 'FooError' exception to be thrown!") + except Exception as err: + if type(err).__name__ != "FooError": + fail( + f"Expected 'FooError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_host_with_path_request_host_with_path_operation() -> None: + """Custom endpoints supplied by users can have paths""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/custom", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HostWithPathOperationInput() + + try: + await client.host_with_path_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/custom/HostWithPathOperation" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_http_checksum_required_request_http_checksum_required() -> ( + None +): + """Adds Content-MD5 header""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpChecksumRequiredInput(foo="base64 encoded md5 checksum") + + try: + await client.http_checksum_required(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/HttpChecksumRequired" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-md5", "iB0/3YSo7maijL0IGOgA9g=="), + ("content-type", "application/json"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "foo":"base64 encoded md5 checksum"\n}\n' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_empty_prefix_headers_request_client_request_http_empty_prefix_headers() -> ( + None +): + """Serializes all request headers, using specific when present""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpEmptyPrefixHeadersInput( + prefix_headers={"x-foo": "Foo", "hello": "Hello"}, specific_header="There" + ) + + try: + await client.http_empty_prefix_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/HttpEmptyPrefixHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("hello", "There"), ("x-foo", "Foo")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_empty_prefix_headers_response_client_response_http_empty_prefix_headers() -> ( + None +): + """Deserializes all response headers with the same for prefix and specific""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("hello", "There"), ("x-foo", "Foo")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpEmptyPrefixHeadersInput() + + try: + actual = await client.http_empty_prefix_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpEmptyPrefixHeadersOutput( + prefix_headers={"x-foo": "Foo", "hello": "There"}, specific_header="There" + ) + + assert actual == expected + + +async def test_rest_json_enum_payload_request_request_http_enum_payload() -> None: + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpEnumPayloadInput(payload="enumvalue") + + try: + await client.http_enum_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/EnumPayload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "text/plain")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"enumvalue" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_enum_payload_response_response_http_enum_payload() -> None: + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("Content-Type", "text/plain")], body=b"enumvalue" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpEnumPayloadInput() + + try: + actual = await client.http_enum_payload(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpEnumPayloadOutput(payload="enumvalue") + + assert actual == expected + + +async def test_rest_json_http_payload_traits_with_blob_request_http_payload_traits() -> ( + None +): + """Serializes a blob in the HTTP payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadTraitsInput(foo="Foo", blob=b"blobby blob blob") + + try: + await client.http_payload_traits(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/HttpPayloadTraits" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/octet-stream"), + ("x-foo", "Foo"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"blobby blob blob" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_payload_traits_with_no_blob_body_request_http_payload_traits() -> ( + None +): + """Serializes an empty blob in the HTTP payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadTraitsInput(foo="Foo") + + try: + await client.http_payload_traits(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/HttpPayloadTraits" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("x-foo", "Foo")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_payload_traits_with_blob_response_http_payload_traits() -> ( + None +): + """Serializes a blob in the HTTP payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("X-Foo", "Foo")], body=b"blobby blob blob" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadTraitsInput() + + try: + actual = await client.http_payload_traits(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpPayloadTraitsOutput(foo="Foo", blob=b"blobby blob blob") + + assert actual == expected + + +async def test_rest_json_http_payload_traits_with_no_blob_body_response_http_payload_traits() -> ( + None +): + """Serializes an empty blob in the HTTP payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("X-Foo", "Foo")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadTraitsInput() + + try: + actual = await client.http_payload_traits(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpPayloadTraitsOutput(foo="Foo", blob=b"") + + assert actual == expected + + +async def test_rest_json_http_payload_traits_with_media_type_with_blob_request_http_payload_traits_with_media_type() -> ( + None +): + """Serializes a blob in the HTTP payload with a content-type""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadTraitsWithMediaTypeInput(foo="Foo", blob=b"blobby blob blob") + + try: + await client.http_payload_traits_with_media_type(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/HttpPayloadTraitsWithMediaType" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "text/plain"), + ("x-foo", "Foo"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"blobby blob blob" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_payload_traits_with_media_type_with_blob_response_http_payload_traits_with_media_type() -> ( + None +): + """Serializes a blob in the HTTP payload with a content-type""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/plain"), ("X-Foo", "Foo")], + body=b"blobby blob blob", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadTraitsWithMediaTypeInput() + + try: + actual = await client.http_payload_traits_with_media_type(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpPayloadTraitsWithMediaTypeOutput( + foo="Foo", blob=b"blobby blob blob" + ) + + assert actual == expected + + +async def test_rest_json_http_payload_with_structure_request_http_payload_with_structure() -> ( + None +): + """Serializes a structure in the payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadWithStructureInput( + nested=NestedPayload(greeting="hello", name="Phreddy") + ) + + try: + await client.http_payload_with_structure(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/HttpPayloadWithStructure" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "greeting": "hello",\n "name": "Phreddy"\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_payload_with_structure_response_http_payload_with_structure() -> ( + None +): + """Serializes a structure in the payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "greeting": "hello",\n "name": "Phreddy"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadWithStructureInput() + + try: + actual = await client.http_payload_with_structure(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpPayloadWithStructureOutput( + nested=NestedPayload(greeting="hello", name="Phreddy") + ) + + assert actual == expected + + +async def test_rest_json_http_payload_with_structure_and_empty_response_body_response_http_payload_with_structure() -> ( + None +): + """Serializes a structure in the payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient(status=200, headers=[], body=b""), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadWithStructureInput() + + try: + actual = await client.http_payload_with_structure(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpPayloadWithStructureOutput(nested=None) + + assert actual == expected + + +async def test_rest_json_http_payload_with_union_request_http_payload_with_union() -> ( + None +): + """Serializes a union in the payload.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadWithUnionInput(nested=UnionPayloadGreeting(value="hello")) + + try: + await client.http_payload_with_union(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/HttpPayloadWithUnion" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "greeting": "hello"\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_payload_with_unset_union_request_http_payload_with_union() -> ( + None +): + """No payload is sent if the union has no value.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadWithUnionInput() + + try: + await client.http_payload_with_union(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/HttpPayloadWithUnion" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_payload_with_union_response_http_payload_with_union() -> ( + None +): + """Serializes a union in the payload.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "greeting": "hello"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadWithUnionInput() + + try: + actual = await client.http_payload_with_union(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpPayloadWithUnionOutput( + nested=UnionPayloadGreeting(value="hello") + ) + + assert actual == expected + + +async def test_rest_json_http_payload_with_unset_union_response_http_payload_with_union() -> ( + None +): + """No payload is sent if the union has no value.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("Content-Length", "0")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPayloadWithUnionInput() + + try: + actual = await client.http_payload_with_union(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpPayloadWithUnionOutput() + + assert actual == expected + + +async def test_rest_json_http_prefix_headers_are_present_request_http_prefix_headers() -> ( + None +): + """Adds headers by prefix""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPrefixHeadersInput( + foo="Foo", foo_map={"abc": "Abc value", "def": "Def value"} + ) + + try: + await client.http_prefix_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/HttpPrefixHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-foo", "Foo"), + ("x-foo-abc", "Abc value"), + ("x-foo-def", "Def value"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_prefix_headers_are_not_present_request_http_prefix_headers() -> ( + None +): + """No prefix headers are serialized because the value is not present""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPrefixHeadersInput(foo="Foo", foo_map={}) + + try: + await client.http_prefix_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/HttpPrefixHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("x-foo", "Foo")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_prefix_empty_headers_request_http_prefix_headers() -> ( + None +): + """Serialize prefix headers were the value is present but empty""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPrefixHeadersInput(foo_map={"abc": ""}) + + try: + await client.http_prefix_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/HttpPrefixHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("x-foo-abc", "")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_prefix_headers_are_present_response_http_prefix_headers() -> ( + None +): + """Adds headers by prefix""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[ + ("x-foo", "Foo"), + ("x-foo-abc", "Abc value"), + ("x-foo-def", "Def value"), + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPrefixHeadersInput() + + try: + actual = await client.http_prefix_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpPrefixHeadersOutput( + foo="Foo", foo_map={"abc": "Abc value", "def": "Def value"} + ) + + assert actual == expected + + +async def test_http_prefix_headers_response_response_http_prefix_headers_in_response() -> ( + None +): + """(de)serializes all response headers""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("hello", "Hello"), ("x-foo", "Foo")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpPrefixHeadersInResponseInput() + + try: + actual = await client.http_prefix_headers_in_response(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpPrefixHeadersInResponseOutput( + prefix_headers={"x-foo": "Foo", "hello": "Hello"} + ) + + assert actual == expected + + +async def test_http_query_params_only_request_request_http_query_params_only_operation() -> ( + None +): + """ + Test that httpQueryParams are included in request when no other query + parameters exist + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpQueryParamsOnlyOperationInput(query_map={"a": "b", "c": "d"}) + + try: + await client.http_query_params_only_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/http-query-params-only" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["a=b", "c=d"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_http_query_params_only_empty_request_request_http_query_params_only_operation() -> ( + None +): + """Test that empty httpQueryParams map results in no query parameters""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpQueryParamsOnlyOperationInput(query_map={}) + + try: + await client.http_query_params_only_operation(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/http-query-params-only" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_na_n_float_labels_request_http_request_with_float_labels() -> ( + None +): + """Supports handling NaN float label values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpRequestWithFloatLabelsInput(float_=float("nan"), double=float("nan")) + + try: + await client.http_request_with_float_labels(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/FloatHttpLabels/NaN/NaN" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_infinity_float_labels_request_http_request_with_float_labels() -> ( + None +): + """Supports handling Infinity float label values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpRequestWithFloatLabelsInput(float_=float("inf"), double=float("inf")) + + try: + await client.http_request_with_float_labels(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/FloatHttpLabels/Infinity/Infinity" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_negative_infinity_float_labels_request_http_request_with_float_labels() -> ( + None +): + """Supports handling -Infinity float label values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpRequestWithFloatLabelsInput(float_=float("-inf"), double=float("-inf")) + + try: + await client.http_request_with_float_labels(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/FloatHttpLabels/-Infinity/-Infinity" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_request_with_greedy_label_in_path_request_http_request_with_greedy_label_in_path() -> ( + None +): + """Serializes greedy labels and normal labels""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpRequestWithGreedyLabelInPathInput(foo="hello/escape", baz="there/guy") + + try: + await client.http_request_with_greedy_label_in_path(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert ( + actual.destination.path + == "/HttpRequestWithGreedyLabelInPath/foo/hello%2Fescape/baz/there/guy" + ) + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_input_with_headers_and_all_params_request_http_request_with_labels() -> ( + None +): + """Sends a GET request that uses URI label bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpRequestWithLabelsInput( + string="string", + short=1, + integer=2, + long=3, + float_=float(4.1), + double=float(5.1), + boolean=True, + timestamp=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + ) + + try: + await client.http_request_with_labels(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert ( + actual.destination.path + == "/HttpRequestWithLabels/string/1/2/3/4.1/5.1/true/2019-12-16T23%3A48%3A18Z" + ) + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_request_label_escaping_request_http_request_with_labels() -> ( + None +): + """Sends a GET request that uses URI label bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpRequestWithLabelsInput( + string=" %:/?#[]@!$&'()*+,;=😹", + short=1, + integer=2, + long=3, + float_=float(4.1), + double=float(5.1), + boolean=True, + timestamp=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + ) + + try: + await client.http_request_with_labels(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert ( + actual.destination.path + == "/HttpRequestWithLabels/%20%25%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D%F0%9F%98%B9/1/2/3/4.1/5.1/true/2019-12-16T23%3A48%3A18Z" + ) + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_request_with_labels_and_timestamp_format_request_http_request_with_labels_and_timestamp_format() -> ( + None +): + """Serializes different timestamp formats in URI labels""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpRequestWithLabelsAndTimestampFormatInput( + member_epoch_seconds=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + member_http_date=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + member_date_time=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + default_format=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + target_epoch_seconds=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + target_http_date=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + target_date_time=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + ) + + try: + await client.http_request_with_labels_and_timestamp_format(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert ( + actual.destination.path + == "/HttpRequestWithLabelsAndTimestampFormat/1576540098/Mon%2C%2016%20Dec%202019%2023%3A48%3A18%20GMT/2019-12-16T23%3A48%3A18Z/2019-12-16T23%3A48%3A18Z/1576540098/Mon%2C%2016%20Dec%202019%2023%3A48%3A18%20GMT/2019-12-16T23%3A48%3A18Z" + ) + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_tolerates_regex_chars_in_segments_request_http_request_with_regex_literal() -> ( + None +): + """Path matching is not broken by regex expressions in literal segments""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpRequestWithRegexLiteralInput(str_="abc") + + try: + await client.http_request_with_regex_literal(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/ReDosLiteral/abc/(a+)+" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_response_code_response_http_response_code() -> None: + """ + Binds the http response code to an output structure. Note that even + though all members are bound outside of the payload, an empty JSON + object is serialized in the response. However, clients should be able to + handle an empty JSON object or an empty payload without failing to + deserialize a response. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=201, headers=[("Content-Type", "application/json")], body=b"{}" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpResponseCodeInput() + + try: + actual = await client.http_response_code(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpResponseCodeOutput(status=201) + + assert actual == expected + + +async def test_rest_json_http_response_code_with_no_payload_response_http_response_code() -> ( + None +): + """ + This test ensures that clients gracefully handle cases where the service + responds with no payload rather than an empty JSON object. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient(status=201, headers=[], body=b""), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpResponseCodeInput() + + try: + actual = await client.http_response_code(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpResponseCodeOutput(status=201) + + assert actual == expected + + +async def test_rest_json_string_payload_request_request_http_string_payload() -> None: + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpStringPayloadInput(payload="rawstring") + + try: + await client.http_string_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/StringPayload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "text/plain")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"rawstring" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_string_payload_response_response_http_string_payload() -> None: + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("Content-Type", "text/plain")], body=b"rawstring" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = HttpStringPayloadInput() + + try: + actual = await client.http_string_payload(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = HttpStringPayloadOutput(payload="rawstring") + + assert actual == expected + + +async def test_rest_json_ignore_query_params_in_response_response_ignore_query_params_in_response() -> ( + None +): + """ + Query parameters must be ignored when serializing the output of an + operation. As of January 2021, server implementations are expected to + respond with a JSON object regardless of if the output parameters are + empty. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{"baz":"bam"}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = IgnoreQueryParamsInResponseInput() + + try: + actual = await client.ignore_query_params_in_response(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = IgnoreQueryParamsInResponseOutput(baz="bam") + + assert actual == expected + + +async def test_rest_json_input_and_output_with_string_headers_request_input_and_output_with_headers() -> ( + None +): + """Tests requests with string header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput( + header_string="Hello", + header_string_list=["a", "b", "c"], + header_string_set=["a", "b", "c"], + ) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-string", "Hello"), + ("x-stringlist", "a"), + ("x-stringlist", "b"), + ("x-stringlist", "c"), + ("x-stringset", "a"), + ("x-stringset", "b"), + ("x-stringset", "c"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_input_and_output_with_quoted_string_headers_request_input_and_output_with_headers() -> ( + None +): + """Tests requests with string list header bindings that require quoting""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput(header_string_list=["b,c", '"def"', "a"]) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-stringlist", "b,c"), + ("x-stringlist", '"def"'), + ("x-stringlist", "a"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_input_and_output_with_numeric_headers_request_input_and_output_with_headers() -> ( + None +): + """Tests requests with numeric header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput( + header_byte=1, + header_short=123, + header_integer=123, + header_long=123, + header_float=float(1.1), + header_double=float(1.1), + header_integer_list=[1, 2, 3], + ) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-byte", "1"), + ("x-double", "1.1"), + ("x-float", "1.1"), + ("x-integer", "123"), + ("x-integerlist", "1"), + ("x-integerlist", "2"), + ("x-integerlist", "3"), + ("x-long", "123"), + ("x-short", "123"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_input_and_output_with_boolean_headers_request_input_and_output_with_headers() -> ( + None +): + """Tests requests with boolean header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput( + header_true_bool=True, + header_false_bool=False, + header_boolean_list=[True, False, True], + ) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-boolean1", "true"), + ("x-boolean2", "false"), + ("x-booleanlist", "true"), + ("x-booleanlist", "false"), + ("x-booleanlist", "true"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_input_and_output_with_timestamp_headers_request_input_and_output_with_headers() -> ( + None +): + """Tests requests with timestamp header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput( + header_timestamp_list=[ + datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + ] + ) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-timestamplist", "Mon, 16 Dec 2019 23:48:18 GMT"), + ("x-timestamplist", "Mon, 16 Dec 2019 23:48:18 GMT"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_input_and_output_with_enum_headers_request_input_and_output_with_headers() -> ( + None +): + """Tests requests with enum header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput( + header_enum="Foo", header_enum_list=["Foo", "Bar", "Baz"] + ) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-enum", "Foo"), + ("x-enumlist", "Foo"), + ("x-enumlist", "Bar"), + ("x-enumlist", "Baz"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_input_and_output_with_int_enum_headers_request_input_and_output_with_headers() -> ( + None +): + """Tests requests with intEnum header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput( + header_integer_enum=1, header_integer_enum_list=[1, 2, 3] + ) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-integerenum", "1"), + ("x-integerenumlist", "1"), + ("x-integerenumlist", "2"), + ("x-integerenumlist", "3"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_na_n_float_header_inputs_request_input_and_output_with_headers() -> ( + None +): + """Supports handling NaN float header values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput( + header_float=float("nan"), header_double=float("nan") + ) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-double", "NaN"), + ("x-float", "NaN"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_infinity_float_header_inputs_request_input_and_output_with_headers() -> ( + None +): + """Supports handling Infinity float header values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput( + header_float=float("inf"), header_double=float("inf") + ) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-double", "Infinity"), + ("x-float", "Infinity"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_negative_infinity_float_header_inputs_request_input_and_output_with_headers() -> ( + None +): + """Supports handling -Infinity float header values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput( + header_float=float("-inf"), header_double=float("-inf") + ) + + try: + await client.input_and_output_with_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/InputAndOutputWithHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-double", "-Infinity"), + ("x-float", "-Infinity"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_input_and_output_with_string_headers_response_input_and_output_with_headers() -> ( + None +): + """Tests responses with string header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[ + ("X-String", "Hello"), + ("X-StringList", "a, b, c"), + ("X-StringSet", "a, b, c"), + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_string="Hello", + header_string_list=["a", "b", "c"], + header_string_set=["a", "b", "c"], + ) + + assert actual == expected + + +async def test_rest_json_input_and_output_with_quoted_string_headers_response_input_and_output_with_headers() -> ( + None +): + """Tests responses with string list header bindings that require quoting""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("X-StringList", '"b,c", "\\"def\\"", a')], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_string_list=["b,c", '"def"', "a"] + ) + + assert actual == expected + + +async def test_rest_json_input_and_output_with_numeric_headers_response_input_and_output_with_headers() -> ( + None +): + """Tests responses with numeric header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[ + ("X-Byte", "1"), + ("X-Double", "1.1"), + ("X-Float", "1.1"), + ("X-Integer", "123"), + ("X-IntegerList", "1, 2, 3"), + ("X-Long", "123"), + ("X-Short", "123"), + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_byte=1, + header_short=123, + header_integer=123, + header_long=123, + header_float=float(1.1), + header_double=float(1.1), + header_integer_list=[1, 2, 3], + ) + + assert actual == expected + + +async def test_rest_json_input_and_output_with_boolean_headers_response_input_and_output_with_headers() -> ( + None +): + """Tests responses with boolean header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[ + ("X-Boolean1", "true"), + ("X-Boolean2", "false"), + ("X-BooleanList", "true, false, true"), + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_true_bool=True, + header_false_bool=False, + header_boolean_list=[True, False, True], + ) + + assert actual == expected + + +async def test_rest_json_input_and_output_with_timestamp_headers_response_input_and_output_with_headers() -> ( + None +): + """Tests responses with timestamp header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[ + ( + "X-TimestampList", + "Mon, 16 Dec 2019 23:48:18 GMT, Mon, 16 Dec 2019 23:48:18 GMT", + ) + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_timestamp_list=[ + datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + ] + ) + + assert actual == expected + + +async def test_rest_json_input_and_output_with_enum_headers_response_input_and_output_with_headers() -> ( + None +): + """Tests responses with enum header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("X-Enum", "Foo"), ("X-EnumList", "Foo, Bar, Baz")], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_enum="Foo", header_enum_list=["Foo", "Bar", "Baz"] + ) + + assert actual == expected + + +async def test_rest_json_input_and_output_with_int_enum_headers_response_input_and_output_with_headers() -> ( + None +): + """Tests responses with intEnum header bindings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("X-IntegerEnum", "1"), ("X-IntegerEnumList", "1, 2, 3")], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_integer_enum=1, header_integer_enum_list=[1, 2, 3] + ) + + assert actual == expected + + +@mark.xfail() +async def test_rest_json_supports_na_n_float_header_outputs_response_input_and_output_with_headers() -> ( + None +): + """Supports handling NaN float header values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("X-Double", "NaN"), ("X-Float", "NaN")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_float=float("nan"), header_double=float("nan") + ) + + assert actual == expected + + +async def test_rest_json_supports_infinity_float_header_outputs_response_input_and_output_with_headers() -> ( + None +): + """Supports handling Infinity float header values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("X-Double", "Infinity"), ("X-Float", "Infinity")], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_float=float("inf"), header_double=float("inf") + ) + + assert actual == expected + + +async def test_rest_json_supports_negative_infinity_float_header_outputs_response_input_and_output_with_headers() -> ( + None +): + """Supports handling -Infinity float header values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("X-Double", "-Infinity"), ("X-Float", "-Infinity")], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = InputAndOutputWithHeadersInput() + + try: + actual = await client.input_and_output_with_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = InputAndOutputWithHeadersOutput( + header_float=float("-inf"), header_double=float("-inf") + ) + + assert actual == expected + + +async def test_rest_json_json_blobs_request_json_blobs() -> None: + """Blobs are base64 encoded""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonBlobsInput(data=b"value") + + try: + await client.json_blobs(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonBlobs" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "data": "dmFsdWU="\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_blobs_response_json_blobs() -> None: + """Blobs are base64 encoded""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "data": "dmFsdWU="\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonBlobsInput() + + try: + actual = await client.json_blobs(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonBlobsOutput(data=b"value") + + assert actual == expected + + +async def test_rest_json_json_enums_request_json_enums() -> None: + """Serializes simple scalar properties""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonEnumsInput( + foo_enum1="Foo", + foo_enum2="0", + foo_enum3="1", + foo_enum_list=["Foo", "0"], + foo_enum_set=["Foo", "0"], + foo_enum_map={"hi": "Foo", "zero": "0"}, + ) + + try: + await client.json_enums(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonEnums" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "fooEnum1": "Foo",\n "fooEnum2": "0",\n "fooEnum3": "1",\n "fooEnumList": [\n "Foo",\n "0"\n ],\n "fooEnumSet": [\n "Foo",\n "0"\n ],\n "fooEnumMap": {\n "hi": "Foo",\n "zero": "0"\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_enums_response_json_enums() -> None: + """Serializes simple scalar properties""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "fooEnum1": "Foo",\n "fooEnum2": "0",\n "fooEnum3": "1",\n "fooEnumList": [\n "Foo",\n "0"\n ],\n "fooEnumSet": [\n "Foo",\n "0"\n ],\n "fooEnumMap": {\n "hi": "Foo",\n "zero": "0"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonEnumsInput() + + try: + actual = await client.json_enums(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonEnumsOutput( + foo_enum1="Foo", + foo_enum2="0", + foo_enum3="1", + foo_enum_list=["Foo", "0"], + foo_enum_set=["Foo", "0"], + foo_enum_map={"hi": "Foo", "zero": "0"}, + ) + + assert actual == expected + + +async def test_rest_json_json_int_enums_request_json_int_enums() -> None: + """Serializes intEnums as integers""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonIntEnumsInput( + integer_enum1=1, + integer_enum2=2, + integer_enum3=3, + integer_enum_list=[1, 2, 3], + integer_enum_set=[1, 2], + integer_enum_map={"abc": 1, "def": 2}, + ) + + try: + await client.json_int_enums(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonIntEnums" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "integerEnum1": 1,\n "integerEnum2": 2,\n "integerEnum3": 3,\n "integerEnumList": [\n 1,\n 2,\n 3\n ],\n "integerEnumSet": [\n 1,\n 2\n ],\n "integerEnumMap": {\n "abc": 1,\n "def": 2\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_int_enums_response_json_int_enums() -> None: + """Serializes intEnums as integers""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "integerEnum1": 1,\n "integerEnum2": 2,\n "integerEnum3": 3,\n "integerEnumList": [\n 1,\n 2,\n 3\n ],\n "integerEnumSet": [\n 1,\n 2\n ],\n "integerEnumMap": {\n "abc": 1,\n "def": 2\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonIntEnumsInput() + + try: + actual = await client.json_int_enums(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonIntEnumsOutput( + integer_enum1=1, + integer_enum2=2, + integer_enum3=3, + integer_enum_list=[1, 2, 3], + integer_enum_set=[1, 2], + integer_enum_map={"abc": 1, "def": 2}, + ) + + assert actual == expected + + +async def test_rest_json_lists_request_json_lists() -> None: + """Serializes JSON lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonListsInput( + string_list=["foo", "bar"], + string_set=["foo", "bar"], + integer_list=[1, 2], + boolean_list=[True, False], + timestamp_list=[ + datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc), + datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc), + ], + enum_list=["Foo", "0"], + int_enum_list=[1, 2], + nested_string_list=[["foo", "bar"], ["baz", "qux"]], + structure_list=[ + StructureListMember(a="1", b="2"), + StructureListMember(a="3", b="4"), + ], + ) + + try: + await client.json_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonLists" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "stringList": [\n "foo",\n "bar"\n ],\n "stringSet": [\n "foo",\n "bar"\n ],\n "integerList": [\n 1,\n 2\n ],\n "booleanList": [\n true,\n false\n ],\n "timestampList": [\n 1398796238,\n 1398796238\n ],\n "enumList": [\n "Foo",\n "0"\n ],\n "intEnumList": [\n 1,\n 2\n ],\n "nestedStringList": [\n [\n "foo",\n "bar"\n ],\n [\n "baz",\n "qux"\n ]\n ],\n "myStructureList": [\n {\n "value": "1",\n "other": "2"\n },\n {\n "value": "3",\n "other": "4"\n }\n ]\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_lists_empty_request_json_lists() -> None: + """Serializes empty JSON lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonListsInput(string_list=[]) + + try: + await client.json_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonLists" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "stringList": []\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_lists_response_json_lists() -> None: + """Serializes JSON lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "stringList": [\n "foo",\n "bar"\n ],\n "stringSet": [\n "foo",\n "bar"\n ],\n "integerList": [\n 1,\n 2\n ],\n "booleanList": [\n true,\n false\n ],\n "timestampList": [\n 1398796238,\n 1398796238\n ],\n "enumList": [\n "Foo",\n "0"\n ],\n "intEnumList": [\n 1,\n 2\n ],\n "nestedStringList": [\n [\n "foo",\n "bar"\n ],\n [\n "baz",\n "qux"\n ]\n ],\n "myStructureList": [\n {\n "value": "1",\n "other": "2"\n },\n {\n "value": "3",\n "other": "4"\n }\n ]\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonListsInput() + + try: + actual = await client.json_lists(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonListsOutput( + string_list=["foo", "bar"], + string_set=["foo", "bar"], + integer_list=[1, 2], + boolean_list=[True, False], + timestamp_list=[ + datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc), + datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc), + ], + enum_list=["Foo", "0"], + int_enum_list=[1, 2], + nested_string_list=[["foo", "bar"], ["baz", "qux"]], + structure_list=[ + StructureListMember(a="1", b="2"), + StructureListMember(a="3", b="4"), + ], + ) + + assert actual == expected + + +async def test_rest_json_lists_empty_response_json_lists() -> None: + """Serializes empty JSON lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "stringList": []\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonListsInput() + + try: + actual = await client.json_lists(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonListsOutput(string_list=[]) + + assert actual == expected + + +async def test_rest_json_json_maps_request_json_maps() -> None: + """Serializes JSON maps""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonMapsInput( + dense_struct_map={ + "foo": GreetingStruct(hi="there"), + "baz": GreetingStruct(hi="bye"), + } + ) + + try: + await client.json_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonMaps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "denseStructMap": {\n "foo": {\n "hi": "there"\n },\n "baz": {\n "hi": "bye"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serializes_zero_values_in_maps_request_json_maps() -> None: + """Ensure that 0 and false are sent over the wire in all maps and lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonMapsInput(dense_number_map={"x": 0}, dense_boolean_map={"x": False}) + + try: + await client.json_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonMaps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "denseNumberMap": {\n "x": 0\n },\n "denseBooleanMap": {\n "x": false\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serializes_dense_set_map_request_json_maps() -> None: + """A request that contains a dense map of sets.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonMapsInput(dense_set_map={"x": [], "y": ["a", "b"]}) + + try: + await client.json_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonMaps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "denseSetMap": {\n "x": [],\n "y": ["a", "b"]\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_maps_response_json_maps() -> None: + """Deserializes JSON maps""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "denseStructMap": {\n "foo": {\n "hi": "there"\n },\n "baz": {\n "hi": "bye"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonMapsInput() + + try: + actual = await client.json_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonMapsOutput( + dense_struct_map={ + "foo": GreetingStruct(hi="there"), + "baz": GreetingStruct(hi="bye"), + } + ) + + assert actual == expected + + +async def test_rest_json_deserializes_zero_values_in_maps_response_json_maps() -> None: + """Ensure that 0 and false are sent over the wire in all maps and lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "denseNumberMap": {\n "x": 0\n },\n "denseBooleanMap": {\n "x": false\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonMapsInput() + + try: + actual = await client.json_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonMapsOutput( + dense_number_map={"x": 0}, dense_boolean_map={"x": False} + ) + + assert actual == expected + + +async def test_rest_json_deserializes_dense_set_map_response_json_maps() -> None: + """A response that contains a dense map of sets.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "denseSetMap": {\n "x": [],\n "y": ["a", "b"]\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonMapsInput() + + try: + actual = await client.json_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonMapsOutput(dense_set_map={"x": [], "y": ["a", "b"]}) + + assert actual == expected + + +async def test_rest_json_json_timestamps_request_json_timestamps() -> None: + """Tests how normal timestamps are serialized""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput( + normal=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + try: + await client.json_timestamps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonTimestamps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "normal": 1398796238\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_timestamps_with_date_time_format_request_json_timestamps() -> ( + None +): + """ + Ensures that the timestampFormat of date-time works like normal + timestamps + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput( + date_time=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + try: + await client.json_timestamps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonTimestamps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "dateTime": "2014-04-29T18:30:38Z"\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_timestamps_with_date_time_on_target_format_request_json_timestamps() -> ( + None +): + """ + Ensures that the timestampFormat of date-time on the target shape works + like normal timestamps + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput( + date_time_on_target=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + try: + await client.json_timestamps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonTimestamps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "dateTimeOnTarget": "2014-04-29T18:30:38Z"\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_timestamps_with_epoch_seconds_format_request_json_timestamps() -> ( + None +): + """Ensures that the timestampFormat of epoch-seconds works""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput( + epoch_seconds=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + try: + await client.json_timestamps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonTimestamps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "epochSeconds": 1398796238\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_timestamps_with_epoch_seconds_on_target_format_request_json_timestamps() -> ( + None +): + """ + Ensures that the timestampFormat of epoch-seconds on the target shape + works + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput( + epoch_seconds_on_target=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + try: + await client.json_timestamps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonTimestamps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "epochSecondsOnTarget": 1398796238\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_timestamps_with_http_date_format_request_json_timestamps() -> ( + None +): + """Ensures that the timestampFormat of http-date works""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput( + http_date=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + try: + await client.json_timestamps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonTimestamps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "httpDate": "Tue, 29 Apr 2014 18:30:38 GMT"\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_timestamps_with_http_date_on_target_format_request_json_timestamps() -> ( + None +): + """Ensures that the timestampFormat of http-date on the target shape works""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput( + http_date_on_target=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + try: + await client.json_timestamps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/JsonTimestamps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "httpDateOnTarget": "Tue, 29 Apr 2014 18:30:38 GMT"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_json_timestamps_response_json_timestamps() -> None: + """Tests how normal timestamps are serialized""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "normal": 1398796238\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput() + + try: + actual = await client.json_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonTimestampsOutput( + normal=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_rest_json_json_timestamps_with_date_time_format_response_json_timestamps() -> ( + None +): + """ + Ensures that the timestampFormat of date-time works like normal + timestamps + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "dateTime": "2014-04-29T18:30:38Z"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput() + + try: + actual = await client.json_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonTimestampsOutput( + date_time=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_rest_json_json_timestamps_with_date_time_on_target_format_response_json_timestamps() -> ( + None +): + """ + Ensures that the timestampFormat of date-time on the target shape works + like normal timestamps + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "dateTimeOnTarget": "2014-04-29T18:30:38Z"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput() + + try: + actual = await client.json_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonTimestampsOutput( + date_time_on_target=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_rest_json_json_timestamps_with_epoch_seconds_format_response_json_timestamps() -> ( + None +): + """Ensures that the timestampFormat of epoch-seconds works""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "epochSeconds": 1398796238\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput() + + try: + actual = await client.json_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonTimestampsOutput( + epoch_seconds=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_rest_json_json_timestamps_with_epoch_seconds_on_target_format_response_json_timestamps() -> ( + None +): + """ + Ensures that the timestampFormat of epoch-seconds on the target shape + works + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "epochSecondsOnTarget": 1398796238\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput() + + try: + actual = await client.json_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonTimestampsOutput( + epoch_seconds_on_target=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_rest_json_json_timestamps_with_http_date_format_response_json_timestamps() -> ( + None +): + """Ensures that the timestampFormat of http-date works""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "httpDate": "Tue, 29 Apr 2014 18:30:38 GMT"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput() + + try: + actual = await client.json_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonTimestampsOutput( + http_date=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_rest_json_json_timestamps_with_http_date_on_target_format_response_json_timestamps() -> ( + None +): + """Ensures that the timestampFormat of http-date on the target shape works""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "httpDateOnTarget": "Tue, 29 Apr 2014 18:30:38 GMT"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonTimestampsInput() + + try: + actual = await client.json_timestamps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonTimestampsOutput( + http_date_on_target=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + + assert actual == expected + + +async def test_rest_json_serialize_string_union_value_request_json_unions() -> None: + """Serializes a string union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionStringValue(value="foo")) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "stringValue": "foo"\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_boolean_union_value_request_json_unions() -> None: + """Serializes a boolean union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionBooleanValue(value=True)) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "booleanValue": true\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_number_union_value_request_json_unions() -> None: + """Serializes a number union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionNumberValue(value=1)) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "numberValue": 1\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_blob_union_value_request_json_unions() -> None: + """Serializes a blob union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionBlobValue(value=b"foo")) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "blobValue": "Zm9v"\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_timestamp_union_value_request_json_unions() -> None: + """Serializes a timestamp union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionTimestampValue( + value=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "timestampValue": 1398796238\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_enum_union_value_request_json_unions() -> None: + """Serializes an enum union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionEnumValue(value="Foo")) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "enumValue": "Foo"\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_list_union_value_request_json_unions() -> None: + """Serializes a list union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput(contents=MyUnionListValue(value=["foo", "bar"])) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_map_union_value_request_json_unions() -> None: + """Serializes a map union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionMapValue(value={"foo": "bar", "spam": "eggs"}) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_structure_union_value_request_json_unions() -> None: + """Serializes a structure union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_renamed_structure_union_value_request_json_unions() -> ( + None +): + """Serializes a renamed structure union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionRenamedStructureValue( + value=RenamedGreeting(salutation="hello!") + ) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "contents": {\n "renamedStructureValue": {\n "salutation": "hello!"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serialize_nested_union_value_request_json_unions() -> None: + """Serializes a nested union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput( + contents=MyUnionUnionValue(value=NestedUnionStringValue(value="foo")) + ) + + try: + await client.json_unions(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/JsonUnions" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "contents": {\n "unionValue": {\n "stringValue": "foo"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_deserialize_string_union_value_response_json_unions() -> None: + """Deserializes a string union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "stringValue": "foo"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionStringValue(value="foo")) + + assert actual == expected + + +async def test_rest_json_deserialize_boolean_union_value_response_json_unions() -> None: + """Deserializes a boolean union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "booleanValue": true\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionBooleanValue(value=True)) + + assert actual == expected + + +async def test_rest_json_deserialize_number_union_value_response_json_unions() -> None: + """Deserializes a number union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "numberValue": 1\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionNumberValue(value=1)) + + assert actual == expected + + +async def test_rest_json_deserialize_blob_union_value_response_json_unions() -> None: + """Deserializes a blob union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "blobValue": "Zm9v"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionBlobValue(value=b"foo")) + + assert actual == expected + + +async def test_rest_json_deserialize_timestamp_union_value_response_json_unions() -> ( + None +): + """Deserializes a timestamp union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "timestampValue": 1398796238\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionTimestampValue( + value=datetime(2014, 4, 29, 18, 30, 38, 0, timezone.utc) + ) + ) + + assert actual == expected + + +async def test_rest_json_deserialize_enum_union_value_response_json_unions() -> None: + """Deserializes an enum union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "enumValue": "Foo"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionEnumValue(value="Foo")) + + assert actual == expected + + +async def test_rest_json_deserialize_list_union_value_response_json_unions() -> None: + """Deserializes a list union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "listValue": ["foo", "bar"]\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput(contents=MyUnionListValue(value=["foo", "bar"])) + + assert actual == expected + + +async def test_rest_json_deserialize_map_union_value_response_json_unions() -> None: + """Deserializes a map union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "mapValue": {\n "foo": "bar",\n "spam": "eggs"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionMapValue(value={"foo": "bar", "spam": "eggs"}) + ) + + assert actual == expected + + +async def test_rest_json_deserialize_structure_union_value_response_json_unions() -> ( + None +): + """Deserializes a structure union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + assert actual == expected + + +async def test_rest_json_deserialize_nested_union_value_response_json_unions() -> None: + """Deserializes a nested union value""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "unionValue": {\n "stringValue": "foo"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionUnionValue(value=NestedUnionStringValue(value="foo")) + ) + + assert actual == expected + + +async def test_rest_json_deserialize_ignore_type_response_json_unions() -> None: + """Ignores an unrecognized __type property""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "contents": {\n "__type": "aws.protocoltests.json10#MyUnion",\n "structureValue": {\n "hi": "hello"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = JsonUnionsInput() + + try: + actual = await client.json_unions(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = JsonUnionsOutput( + contents=MyUnionStructureValue(value=GreetingStruct(hi="hello")) + ) + + assert actual == expected + + +async def test_media_type_header_input_base64_request_media_type_header() -> None: + """Headers that target strings with a mediaType are base64 encoded""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = MediaTypeHeaderInput(json="true") + + try: + await client.media_type_header(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/MediaTypeHeader" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("x-json", "dHJ1ZQ==")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_media_type_header_output_base64_response_media_type_header() -> None: + """Headers that target strings with a mediaType are base64 encoded""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("X-Json", "dHJ1ZQ==")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = MediaTypeHeaderInput() + + try: + actual = await client.media_type_header(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = MediaTypeHeaderOutput(json="true") + + assert actual == expected + + +async def test_rest_json_no_input_and_no_output_request_no_input_and_no_output() -> ( + None +): + """ + No input serializes no payload. When clients do not need to serialize + any data in the payload, they should omit a payload altogether. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndNoOutputInput() + + try: + await client.no_input_and_no_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/NoInputAndNoOutput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_no_input_and_no_output_response_no_input_and_no_output() -> ( + None +): + """ + When an operation does not define output, the service will respond with + an empty payload, and may optionally include the content-type header. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient(status=200, headers=[], body=b""), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndNoOutputInput() + + try: + actual = await client.no_input_and_no_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndNoOutputOutput() + + assert actual == expected + + +async def test_rest_json_no_input_and_output_request_no_input_and_output() -> None: + """ + No input serializes no payload. When clients do not need to serialize + any data in the payload, they should omit a payload altogether. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndOutputInput() + + try: + await client.no_input_and_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/NoInputAndOutputOutput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_no_input_and_output_with_json_response_no_input_and_output() -> ( + None +): + """ + Operations that define output and do not bind anything to the payload + return a JSON object in the response. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("Content-Type", "application/json")], body=b"{}" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndOutputInput() + + try: + actual = await client.no_input_and_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndOutputOutput() + + assert actual == expected + + +async def test_rest_json_no_input_and_output_no_payload_response_no_input_and_output() -> ( + None +): + """ + This test is similar to RestJsonNoInputAndOutputWithJson, but it ensures + that clients can gracefully handle responses that omit a JSON payload. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient(status=200, headers=[], body=b""), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NoInputAndOutputInput() + + try: + actual = await client.no_input_and_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = NoInputAndOutputOutput() + + assert actual == expected + + +async def test_rest_json_null_and_empty_headers_request_null_and_empty_headers_client() -> ( + None +): + """ + Do not send null values, but do send empty strings and empty lists over + the wire in headers + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = NullAndEmptyHeadersClientInput(a=None, b="", c=[]) + + try: + await client.null_and_empty_headers_client(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/NullAndEmptyHeadersClient" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("x-b", "")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set(["x-a"]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_omits_null_query_request_omits_null_serializes_empty_string() -> ( + None +): + """Omits null query values""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OmitsNullSerializesEmptyStringInput(null_value=None) + + try: + await client.omits_null_serializes_empty_string(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/OmitsNullSerializesEmptyString" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serializes_empty_query_value_request_omits_null_serializes_empty_string() -> ( + None +): + """Serializes empty query strings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OmitsNullSerializesEmptyStringInput(empty_string="") + + try: + await client.omits_null_serializes_empty_string(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/OmitsNullSerializesEmptyString" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["Empty="] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_omits_empty_list_query_values_request_omits_serializing_empty_lists() -> ( + None +): + """Supports omitting empty lists.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OmitsSerializingEmptyListsInput( + query_string_list=[], + query_integer_list=[], + query_double_list=[], + query_boolean_list=[], + query_timestamp_list=[], + query_enum_list=[], + query_integer_enum_list=[], + ) + + try: + await client.omits_serializing_empty_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/OmitsSerializingEmptyLists" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_client_populates_default_values_in_input_request_operation_with_defaults() -> ( + None +): + """Client populates default values in input.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput(defaults=Defaults()) + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/OperationWithDefaults" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "defaults": {\n "defaultString": "hi",\n "defaultBoolean": true,\n "defaultList": [],\n "defaultDocumentMap": {},\n "defaultDocumentString": "hi",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": [],\n "defaultTimestamp": 0,\n "defaultBlob": "YWJj",\n "defaultByte": 1,\n "defaultShort": 1,\n "defaultInteger": 10,\n "defaultLong": 100,\n "defaultFloat": 1.0,\n "defaultDouble": 1.0,\n "defaultMap": {},\n "defaultEnum": "FOO",\n "defaultIntEnum": 1,\n "emptyString": "",\n "falseBoolean": false,\n "emptyBlob": "",\n "zeroByte": 0,\n "zeroShort": 0,\n "zeroInteger": 0,\n "zeroLong": 0,\n "zeroFloat": 0.0,\n "zeroDouble": 0.0\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_client_skips_top_level_default_values_in_input_request_operation_with_defaults() -> ( + None +): + """Client skips top level default values in input.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput() + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/OperationWithDefaults" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{\n}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_client_uses_explicitly_provided_member_values_over_defaults_request_operation_with_defaults() -> ( + None +): + """Client uses explicitly provided member values over defaults""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput( + defaults=Defaults( + default_string="bye", + default_boolean=True, + default_list=["a"], + default_document_map=Document({"name": "Jack"}), + default_document_string=Document("bye"), + default_document_boolean=Document(True), + default_document_list=Document(["b"]), + default_null_document=Document("notNull"), + default_timestamp=datetime(1970, 1, 1, 0, 0, 1, 0, timezone.utc), + default_blob=b"hi", + default_byte=2, + default_short=2, + default_integer=20, + default_long=200, + default_float=float(2.0), + default_double=float(2.0), + default_map={"name": "Jack"}, + default_enum="BAR", + default_int_enum=2, + empty_string="foo", + false_boolean=True, + empty_blob=b"hi", + zero_byte=1, + zero_short=1, + zero_integer=1, + zero_long=1, + zero_float=float(1.0), + zero_double=float(1.0), + ) + ) + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/OperationWithDefaults" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "defaults": {\n "defaultString": "bye",\n "defaultBoolean": true,\n "defaultList": ["a"],\n "defaultDocumentMap": {"name": "Jack"},\n "defaultDocumentString": "bye",\n "defaultDocumentBoolean": true,\n "defaultDocumentList": ["b"],\n "defaultNullDocument": "notNull",\n "defaultTimestamp": 1,\n "defaultBlob": "aGk=",\n "defaultByte": 2,\n "defaultShort": 2,\n "defaultInteger": 20,\n "defaultLong": 200,\n "defaultFloat": 2.0,\n "defaultDouble": 2.0,\n "defaultMap": {"name": "Jack"},\n "defaultEnum": "BAR",\n "defaultIntEnum": 2,\n "emptyString": "foo",\n "falseBoolean": true,\n "emptyBlob": "aGk=",\n "zeroByte": 1,\n "zeroShort": 1,\n "zeroInteger": 1,\n "zeroLong": 1,\n "zeroFloat": 1.0,\n "zeroDouble": 1.0\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_client_uses_explicitly_provided_values_in_top_level_request_operation_with_defaults() -> ( + None +): + """ + Any time a value is provided for a member in the top level of input, it + is used, regardless of if its the default. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput( + top_level_default="hi", other_top_level_default=0 + ) + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/OperationWithDefaults" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "topLevelDefault": "hi",\n "otherTopLevelDefault": 0\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_client_ignores_non_top_level_defaults_on_members_with_client_optional_request_operation_with_defaults() -> ( + None +): + """ + Typically, non top-level members would have defaults filled in, but if + they have the clientOptional trait, the defaults should be ignored. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput( + client_optional_defaults=ClientOptionalDefaults() + ) + + try: + await client.operation_with_defaults(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/OperationWithDefaults" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "clientOptionalDefaults": {}\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_client_populates_defaults_values_when_missing_in_response_response_operation_with_defaults() -> ( + None +): + """Client populates default values when missing in response.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("Content-Type", "application/json")], body=b"{}" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput() + + try: + actual = await client.operation_with_defaults(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = OperationWithDefaultsOutput( + default_string="hi", + default_boolean=True, + default_list=[], + default_document_map=Document({}), + default_document_string=Document("hi"), + default_document_boolean=Document(True), + default_document_list=Document([]), + default_timestamp=datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc), + default_blob=b"abc", + default_byte=1, + default_short=1, + default_integer=10, + default_long=100, + default_float=float(1.0), + default_double=float(1.0), + default_map={}, + default_enum="FOO", + default_int_enum=1, + empty_string="", + false_boolean=False, + empty_blob=b"", + zero_byte=0, + zero_short=0, + zero_integer=0, + zero_long=0, + zero_float=float(0.0), + zero_double=float(0.0), + ) + + assert actual == expected + + +async def test_rest_json_client_ignores_default_values_if_member_values_are_present_in_response_response_operation_with_defaults() -> ( + None +): + """ + Client ignores default values if member values are present in the + response. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "defaultString": "bye",\n "defaultBoolean": false,\n "defaultList": ["a"],\n "defaultDocumentMap": {"name": "Jack"},\n "defaultDocumentString": "bye",\n "defaultDocumentBoolean": false,\n "defaultDocumentList": ["b"],\n "defaultNullDocument": "notNull",\n "defaultTimestamp": 2,\n "defaultBlob": "aGk=",\n "defaultByte": 2,\n "defaultShort": 2,\n "defaultInteger": 20,\n "defaultLong": 200,\n "defaultFloat": 2.0,\n "defaultDouble": 2.0,\n "defaultMap": {"name": "Jack"},\n "defaultEnum": "BAR",\n "defaultIntEnum": 2,\n "emptyString": "foo",\n "falseBoolean": true,\n "emptyBlob": "aGk=",\n "zeroByte": 1,\n "zeroShort": 1,\n "zeroInteger": 1,\n "zeroLong": 1,\n "zeroFloat": 1.0,\n "zeroDouble": 1.0\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithDefaultsInput() + + try: + actual = await client.operation_with_defaults(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = OperationWithDefaultsOutput( + default_string="bye", + default_boolean=False, + default_list=["a"], + default_document_map=Document({"name": "Jack"}), + default_document_string=Document("bye"), + default_document_boolean=Document(False), + default_document_list=Document(["b"]), + default_null_document=Document("notNull"), + default_timestamp=datetime(1970, 1, 1, 0, 0, 2, 0, timezone.utc), + default_blob=b"hi", + default_byte=2, + default_short=2, + default_integer=20, + default_long=200, + default_float=float(2.0), + default_double=float(2.0), + default_map={"name": "Jack"}, + default_enum="BAR", + default_int_enum=2, + empty_string="foo", + false_boolean=True, + empty_blob=b"hi", + zero_byte=1, + zero_short=1, + zero_integer=1, + zero_long=1, + zero_float=float(1.0), + zero_double=float(1.0), + ) + + assert actual == expected + + +async def test_rest_json_client_populates_nested_default_values_when_missing_request_operation_with_nested_structure() -> ( + None +): + """Client populates nested default values when missing.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithNestedStructureInput( + top_level=TopLevel( + dialog=Dialog(language="en"), + dialog_list=[ + Dialog(), + Dialog(farewell=Farewell()), + Dialog( + language="it", + greeting="ciao", + farewell=Farewell(phrase="arrivederci"), + ), + ], + dialog_map={ + "emptyDialog": Dialog(), + "partialEmptyDialog": Dialog(language="en", farewell=Farewell()), + "nonEmptyDialog": Dialog( + greeting="konnichiwa", farewell=Farewell(phrase="sayonara") + ), + }, + ) + ) + + try: + await client.operation_with_nested_structure(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/OperationWithNestedStructure" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "topLevel": {\n "dialog": {\n "language": "en",\n "greeting": "hi"\n },\n "dialogList": [\n {\n "greeting": "hi"\n },\n {\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n "greeting": "hi"\n },\n "partialEmptyDialog": {\n "language": "en",\n "greeting": "hi",\n "farewell": {\n "phrase": "bye"\n }\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_client_populates_nested_defaults_when_missing_in_response_body_response_operation_with_nested_structure() -> ( + None +): + """Client populates nested default values when missing in response body.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "dialog": {\n "language": "en"\n },\n "dialogList": [\n {\n },\n {\n "farewell": {}\n },\n {\n "language": "it",\n "greeting": "ciao",\n "farewell": {\n "phrase": "arrivederci"\n }\n }\n ],\n "dialogMap": {\n "emptyDialog": {\n },\n "partialEmptyDialog": {\n "language": "en",\n "farewell": {}\n },\n "nonEmptyDialog": {\n "greeting": "konnichiwa",\n "farewell": {\n "phrase": "sayonara"\n }\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = OperationWithNestedStructureInput() + + try: + actual = await client.operation_with_nested_structure(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = OperationWithNestedStructureOutput( + dialog=Dialog(language="en", greeting="hi"), + dialog_list=[ + Dialog(greeting="hi"), + Dialog(greeting="hi", farewell=Farewell(phrase="bye")), + Dialog( + language="it", + greeting="ciao", + farewell=Farewell(phrase="arrivederci"), + ), + ], + dialog_map={ + "emptyDialog": Dialog(greeting="hi"), + "partialEmptyDialog": Dialog( + language="en", greeting="hi", farewell=Farewell(phrase="bye") + ), + "nonEmptyDialog": Dialog( + greeting="konnichiwa", farewell=Farewell(phrase="sayonara") + ), + }, + ) + + assert actual == expected + + +async def test_rest_json_input_union_with_unit_member_request_post_player_action() -> ( + None +): + """Unit types in unions are serialized like normal structures in requests.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PostPlayerActionInput(action=PlayerActionQuit(value=Unit())) + + try: + await client.post_player_action(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/PostPlayerAction" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "action": {\n "quit": {}\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_output_union_with_unit_member_response_post_player_action() -> ( + None +): + """Unit types in unions are serialized like normal structures in responses.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "action": {\n "quit": {}\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PostPlayerActionInput() + + try: + actual = await client.post_player_action(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = PostPlayerActionOutput(action=PlayerActionQuit(value=Unit())) + + assert actual == expected + + +async def test_post_union_with_json_name_request1_request_post_union_with_json_name() -> ( + None +): + """Tests that jsonName works with union members.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PostUnionWithJsonNameInput(value=UnionWithJsonNameFoo(value="hi")) + + try: + await client.post_union_with_json_name(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/PostUnionWithJsonName" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "value": {\n "FOO": "hi"\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_post_union_with_json_name_request2_request_post_union_with_json_name() -> ( + None +): + """Tests that jsonName works with union members.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PostUnionWithJsonNameInput(value=UnionWithJsonNameBaz(value="hi")) + + try: + await client.post_union_with_json_name(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/PostUnionWithJsonName" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "value": {\n "_baz": "hi"\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_post_union_with_json_name_request3_request_post_union_with_json_name() -> ( + None +): + """Tests that jsonName works with union members.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PostUnionWithJsonNameInput(value=UnionWithJsonNameBar(value="hi")) + + try: + await client.post_union_with_json_name(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/PostUnionWithJsonName" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "value": {\n "bar": "hi"\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_post_union_with_json_name_response1_response_post_union_with_json_name() -> ( + None +): + """Tests that jsonName works with union members.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "value": {\n "FOO": "hi"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PostUnionWithJsonNameInput() + + try: + actual = await client.post_union_with_json_name(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = PostUnionWithJsonNameOutput(value=UnionWithJsonNameFoo(value="hi")) + + assert actual == expected + + +async def test_post_union_with_json_name_response2_response_post_union_with_json_name() -> ( + None +): + """Tests that jsonName works with union members.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "value": {\n "_baz": "hi"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PostUnionWithJsonNameInput() + + try: + actual = await client.post_union_with_json_name(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = PostUnionWithJsonNameOutput(value=UnionWithJsonNameBaz(value="hi")) + + assert actual == expected + + +async def test_post_union_with_json_name_response3_response_post_union_with_json_name() -> ( + None +): + """Tests that jsonName works with union members.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "value": {\n "bar": "hi"\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PostUnionWithJsonNameInput() + + try: + actual = await client.post_union_with_json_name(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = PostUnionWithJsonNameOutput(value=UnionWithJsonNameBar(value="hi")) + + assert actual == expected + + +@mark.xfail() +async def test_sdk_applied_content_encoding_rest_json1_request_put_with_content_encoding() -> ( + None +): + """ + Compression algorithm encoding is appended to the Content-Encoding + header. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutWithContentEncodingInput( + data="RjCEL3kBwqPivZUXGiyA5JCujtWgJAkKRlnTEsNYfBRGOS0f7LT6R3bCSOXeJ4auSHzQ4BEZZTklUyj5\n1HEojihShQC2jkQJrNdGOZNSW49yRO0XbnGmeczUHbZqZRelLFKW4xjru9uTuB8lFCtwoGgciFsgqTF8\n5HYcoqINTRxuAwGuRUMoNO473QT0BtCQoKUkAyVaypG0hBZdGNoJhunBfW0d3HWTYlzz9pXElyZhq3C1\n2PDB17GEoOYXmTxDecysmPOdo5z6T0HFhujfeJFIQQ8dirmXcG4F3v0bZdf6AZ3jsiVh6RnEXIPxPbOi\ngIXDWTMUr4Pg3f2LdYCM01eAb2qTdgsEN0MUDhEIfn68I2tnWvcozyUFpg1ez6pyWP8ssWVfFrckREIM\nMb0cTUVqSVSM8bnFiF9SoXM6ZoGMKfX1mT708OYk7SqZ1JlCTkecDJDoR5ED2q2MWKUGR6jjnEV0GtD8\nWJO6AcF0DptY9Hk16Bav3z6c5FeBvrGDrxTFVgRUk8SychzjrcqJ4qskwN8rL3zslC0oqobQRnLFOvwJ\nprSzBIwdH2yAuxokXAdVRa1u9NGNRvfWJfKkwbbVz8yV76RUF9KNhAUmwyYDrLnxNj8ROl8B7dv8Gans\n7Bit52wcdiJyjBW1pAodB7zqqVwtBx5RaSpF7kEMXexYXp9N0J1jlXzdeg5Wgg4pO7TJNr2joiPVAiFf\nefwMMCNBkYx2z7cRxVxCJZMXXzxSKMGgdTN24bJ5UgE0TxyV52RC0wGWG49S1x5jGrvmxKCIgYPs0w3Z\n0I3XcdB0WEj4x4xRztB9Cx2Mc4qFYQdzS9kOioAgNBti1rBySZ8lFZM2zqxvBsJTTJsmcKPr1crqiXjM\noVWdM4ObOO6QA7Pu4c1hT68CrTmbcecjFcxHkgsqdixnFtN6keMGL9Z2YMjZOjYYzbUEwLJqUVWalkIB\nBkgBRqZpzxx5nB5t0qDH35KjsfKM5cinQaFoRq9y9Z82xdCoKZOsUbxZkk1kVmy1jPDCBhkhixkc5PKS\nFoSKTbeK7kuCEZCtR9OfF2k2MqbygGFsFu2sgb1Zn2YdDbaRwRGeaLhswta09UNSMUo8aTixgoYVHxwy\nvraLB6olPSPegeLOnmBeWyKmEfPdbpdGm4ev4vA2AUFuLIeFz0LkCSN0NgQMrr8ALEm1UNpJLReg1ZAX\nzZh7gtQTZUaBVdMJokaJpLk6FPxSA6zkwB5TegSqhrFIsmvpY3VNWmTUq7H0iADdh3dRQ8Is97bTsbwu\nvAEOjh4FQ9wPSFzEtcSJeYQft5GfWYPisDImjjvHVFshFFkNy2nN18pJmhVPoJc456tgbdfEIdGhIADC\n6UPcSSzE1FxlPpILqZrp3i4NvvKoiOa4a8tnALd2XRHHmsvALn2Wmfu07b86gZlu4yOyuUFNoWI6tFvd\nbHnqSJYNQlFESv13gJw609DBzNnrIgBGYBAcDRrIGAnflRKwVDUnDFrUQmE8xNG6jRlyb1p2Y2RrfBtG\ncKqhuGNiT2DfxpY89ektZ98waPhJrFEPJToNH8EADzBorh3T0h4YP1IeLmaI7SOxeuVrk1kjRqMK0rUB\nlUJgJNtCE35jCyoHMwPQlyi78ZaVv8COVQ24zcGpw0MTy6JUsDzAC3jLNY6xCb40SZV9XzG7nWvXA5Ej\nYC1gTXxF4AtFexIdDZ4RJbtYMyXt8LsEJerwwpkfqvDwsiFuqYC6vIn9RoZO5kI0F35XtUITDQYKZ4eq\nWBV0itxTyyR5Rp6g30pZEmEqOusDaIh96CEmHpOBYAQZ7u1QTfzRdysIGMpzbx5gj9Dxm2PO1glWzY7P\nlVqQiBlXSGDOkBkrB6SkiAxknt9zsPdTTsf3r3nid4hdiPrZmGWNgjOO1khSxZSzBdltrCESNnQmlnP5\nZOHA0eSYXwy8j4od5ZmjA3IpFOEPW2MutMbxIbJpg5dIx2x7WxespftenRLgl3CxcpPDcnb9w8LCHBg7\nSEjrEer6Y8wVLFWsQiv6nTdCPZz9cGqwgtCaiHRy8lTWFgdfWd397vw9rduGld3uUFeFRGjYrphqEmHi\nhiG0GhE6wRFVUsGJtvOCYkVREvbEdxPFeJvlAvOcs9HKbtptlTusvYB86vR2bNcIY4f5JZu2X6sGa354\n7LRk0ps2zqYjat3hMR7XDC8KiKceBteFsXoDjfVxTYKelpedTxqWAafrKhaoAVuNM98PSnkuIWGzjSUC\nNsDJTt6vt1D1afBVPWVmnQ7ZQdtEtLIEwAWYjemAztreELIr1E9fPEILm1Ke4KctP9I0I72Dh4eylNZD\n0DEr2Hg7cWFckuZ0Av5d0IPRARXikEGDHl8uh12TXL9v2Uh0ZVSJMEYvxGSbZvkWz8TjWSk3hKA2a7GL\nJm3Ho7e1C34gE1XRGcEthxvURxt4OKBqN3ZNaMIuDTWinoQAutMcUqtm4MoL7RGPiCHUrvTwQPSirsmA\nQmOEu8nOpnP77Fivh9jLGx5ta7nL6jrsWUsBqiN1lzpdPYLRR4mUIAj6sNWiDEk4pkbHSMEcqbWw6Zl7\npsEyPDHalCNhWMA3RSK3skURzQDZ0oBV5W7vjVIZ4d3uCKsk6zrzEI9u5mx7p9RdNKodXfzqYt0ULdtc\n3RW0hIfw2KvrO3BD2QrtgAkfrFBGVvlJSUoh0MvLz8DeXxfuiuq9Ttu7wvsqVI4Piah6WNEXtHHGPJO3\nGhc75Bnv2To4VS2v8rmyKAPIIVTuYBHZN6sZ4FhFzbrslCIdk0eadaU60naqiNWU3CsxplIYGyeThmJ7\n9u4h6Y2OmiPZjFPS2bAzwgAozYTVefII9aEaWZ0hxHZeu1FW7r79dkdO73ZqRfas9u8Z7LLBPCw5pV0F\n5I0pHDgNb6MogoxF4NZJfVtIX1vCHhhVLrXjrYNJU2fD9Fw8kT8Ie2HDBJnqAvYKmryQ1r9ulo3Me3rH\nq9s2Y5uCDxu9iQNhnpwIm57WYGFeqd2fnQeY2IziD3Jgx0KSrmOH0jgi0RwJyfGXaORPq3bQQqljuACo\nkO6io9t5VI8PbNxSHTRbtYiPciUslbT0g7SpCLrRPOBRJ4DDk56pjghpeoUagJ5xJ4wjBzBuXnAGkNnP\nTfpiuz2r3oSBAi8sB9wiYK2z9sp4gZyQsqdVNzAEgKatOxBRBmJCBYpjO98ZQrF83XApPpfFg0ujB2PW\n1iYF9NkgwIKB5oB6KVTOmSKJk11mVermPgeugHbzdd2zUP6fP8fWbhseqk2t8ahGvqjs2CDHFIWXl5jc\nfCknbykE3ANt7lnAfJQ2ddduLGiqrX4HWx6jcWw08Es6BkleO0IDbaWrb95d5isvFlzJsf0TyDIXF4uq\nbBDCi0XPWqtRJ2iqmnJa2GbBe9GmAOWMkBFSilMyC4sR395WSDpD56fx0NGoU6cHrRu9xF2Bgh7RGSfl\nch2GXEeE02fDpSHFNvJBlOEqqfkIX6oCa6KY9NThqeIjYsT184XR2ZI7akXRaw1gMOGpk4FmUxk6WIuX\n4ei1SLQgSdl7OEdRtJklZ76eFrMbkJQ2TDhu8f7mVuiy53GUMIvCrP9xYGZGmCIDm2e4U2BDi3F7C5xK\n3bDZXwlQp6z4BSqTy2OVEWxXUJfjPMOL5Mc7AvDeKtxAS73pVIv0HgHIa4NBAdC7uLG0zXuu1FF6z2XY\nyUhk03fMZhYe7vVxsul3WE7U01fuN8z2y0eKwBW1RFBE1eKIaR9Y01sIWQWbSrfHfDrdZiElhmhHehfs\n0EfrR4sLYdQshJuvhTeKGJDaEhtPQwwJ9mUYGtuCL9RozWx1XI4bHNlzBTW0BVokYiJGlPe7wdxNzJD7\nJgS7Lwv6jGKngVf86imGZyzqwiteWFPdNUoWdTvUPSMO5xIUK9mo5QpwbBOAmyYzVq42o3Qs90N9khEV\nU36LB99fw8PtGHH5wsCHshfauwnNPj0blGXzke0kQ4JNCVH7Jtn0Y0aeejkSxFtwtxoYs6zHl1Lxxpsd\nsw5vBy49CEtoltDW367lVAwDjWdx20msGB7qJCkEDrzu7EXSO22782QX9NBRcN9ppX0C25I0FMA4Wnhz\n9zIpiXRrsTH35jzM8Cjt4EVLGNU3O0HuEvAer3cENnMJtngdrT86ox3fihMQbiuy4Bh4DEcP5in2VjbT\n3qbnoCNvOi8Fmmf7KlGlWAOceL5OHVE5lljjQEMzEQOCEgrk5mDKgwSBJQBNauIDSC1a5iEQjB8Xxp4C\nqeKyyWY9IOntNrtU5ny4lNprHJd36dKFeBLKcGCOvgHBXdOZloMF0YTRExw7hreEO9IoTGVHJ4teWsNr\nHdtagUHjkeZkdMMfnUGNv5aBNtFMqhcZH6EitEa9lGPkKBbJpoom3u8D8EHSIF1H5EZqqx9TLY5hWAIG\nPwJ4qwkpCGw5rCLVrjw7ARKukIFzNULANqjHUMcJ002TlUosJM4xJ4aAgckpLVGOGuPDhGAAexEcQmbg\nUsZdmqQrtuVUyyLteLbLbqtR6CTlcAIwY3xyMCmPgyefE0FEUODBoxQtRUuYTL9RC5o1sYb2PvcxUQfb\niJFi2CAl99pAzcckU2qVCxniARslIxM5pmMRGsQX9ZzYAfZrbg6ce6S74I8UMlgRQ2QVyvUjKKOE6IrJ\nLng370emHfe5m6LZULD5YiZutkD5ipjL2Bz77DvTE5kNPUhuoKBcTJcUgytfXAKUTWOcRKNlq0GImrxM\nJfr7AWbLFFNKGLeTrVDBwpcokJCv0zcOKWe8fd2xkeXkZTdmM66IgM27cyYmtQ6YF26Kd0qrWJeVZJV9\n3fyLYYvKN5csbRY2BHoYE5ERARRW65IrpkXMf48OrCXMtDIP0Z7wxI9DiTeKKeH4uuguhCJnwzR3WxLA\nVU6eBJEd7ZjS6JA83w7decq8uDI7LGKjcz1FySp3B7fE9DkHRGXxbsL7Fjar6vW2mAv8CuvI20B6jctp\n2yLDs24sPfB3sSxrrlhbuT1m6DZqiN0dl6umKx7NGZhmOTVGr20jfcxhqPQwTJfd7kel4rvxip4BqkvT\n7STy8knJ2BXGyJeNgwo1PXUZRDVy0LCTsSF1RFuRZe8cktHl9lgw8ntdPn1pVFL0MwJkJfdXBNUp5gNv\n50FTkrpo1t6wq4CVbcfj2XOrOzvBUzNH26sXGABI1gGxCdp2jEZrHgqQaWIaTJVTuguZhxqDvdYsrwFW\nYN58uuNcKHIrGdRSigyZInwQDYk0pjcqdSeU0WVU3Y9htzZBR7XRaCJr5YTZvq7fwermb5tuwb37lPLq\nB2IGg0iftkVbXaSyfCwVaRbfLBb88so0QqpmJGirFu8FcDiXOV1zTr8yW9XLdYQuUjh43xrXLdgsuYff\nCagInUk1eU1aLjVZoJRsNmStmOEpAqlYMwTvx7w6j2f421Cxr5cNZBIVlAxlXN2QiDqJ9v3sHhHkTanc\nlQuH8ptUyX8qncpBuXXBn7cSez9N0EoxCBl1GHUagbjstgJo4gzLvTmVIY6MiWYOBitzNUHfyqKwtKUr\nVoSCdZcGeA9lHUPA7PUprRRaT3m1hGKPyshtVS2ikG48w3oVerln1N1qGdtz46gZCrndw3LZ1B362RfW\nzDPuXbpsyLsRMTt1Rz1oKHRXp3iE41hkhQH6pxlvyCW2INnHt5XU8zRamOB3oW0udOhMpQFDjRkOcy06\nb4t0QTHvoRqmBna3WXzIMZyeK3GChF5eF8oDXRbjhk7BB6YKCgqwWUzEJ5K47HMSlhFkBUjaPRjdGM0z\nzOMwhW6b1NvSwP7XM1P5yi1oPvOspts1vr29SXqrMMrBhVogeodWyd69NqrO4jkyBxKmlXifoTowpfiY\n2cUCE0XMZqxUN39LCP09JqZifaEcBEo3mgtm1tWu5QR2GNq7UyQf4RIPSDOpDCAtwoPhRgdT1lJdcj4U\nlnH0wrJ8Uwu7c08L7ErnIrDATqCrOjpSbzGP1xHENABYONC4TknFPrJ8pe40A8fzGT0qBw9mAM1SKcHO\nfoiLcMC9AjHTqJzDG3xplSLPG9or2rMeq7Fzp9r0y7uJRMxgg51EbjfvYlH466A3ggvL2WQlDXjJqPW3\nBJGWAWDNN9LK8f46bADKPxakpkx23S9O47rGSXfDhVSIZsDympxWX1UOzWwMZRHkofVeKqizgbKkGgUT\nWykE9gRoRAOd9wfHZDYKa9i0LaPDiaUMvnU1gdBIqIoiVsdJ9swX47oxvMtOxtcS0zlD6llDkBuIiU5g\nPwRCYmtkkb25c8iRJXwGFPjI1wJ34I1z1ENicPdosPiUe9ZC2jnXIKzEdv01x2ER7DNDF3yxOwOhxNxI\nGqsmC92j25UQQFu9ZstOZ28AoCkuOYs0Uycm5u8jR1T39dMBwrko09rC65ENLnsxM8oebmyFCPiGJ1ED\n5Xqc9qZ237f1OnETAoEOwqUSvrdPTv56U7hV91EMTyC812MLQpr2710E3VVpsUCUMNhIxdt7UXZ1UNFb\njgzpZLXnf4DHrv6B7kq6UI50KMxcw1HZE2GpODfUTzNFLaqdrvzxKe5eUWdcojBaRbD4fFdVYJTElYDH\nNNVh6ofkoeWcs9CWGFmSBe0T4K8phFeygQg0prKMELNEy6qENzVtG9ZDcqj3a7L6ZLtvq50anWp7fAVu\nfwz55g4iM2Z2fA0pnwHDL7tt67zTxGITvsnJsZSpeq1EQsZcwtkBV9liu7Rl7jiVT1IIRtchB8TsTiaA\nwVHIQQ9RIOTiPQdKNqi1kC9iGlUqWK93gblNWlBw1eYB9Wk8FQogutwTf0caNMx8D4nPbANcmOOlskIy\nzALh15OlTrWnhP95rf08AN2J026zDE2DUF9k0eCevYBQIDjqKNW4XCZnjbHoIcKzbY5VzPbMs3ZyMz8K\nSucBmgPg6wrSK5ykbkapS5vuqvXc9GbjQJ8bPNzoxoWGyjbZvDs2OBrIqBmcQb2DLJ8v38McQ4mC4UsS\njf4PyfSCtpk274QZjvLCZbLiCBxQegk7jUU0NmTFJAcYCxd9xMWdlFkiszcltT2YzwuFFz7iA6aa4n5L\nHpBNfUA01GcAi1aCMYhmooS4zSlYcSOZkovMz36U3Fd9WtqIEOJLi7HMgHQDgNMdK6DTzAdHQtxerxVF\nHJnPrfNVG7270r3bp0bPnLNYLhObbAn6zqSAUeLtI2Y4KJDjBKCAh2vvYGbu0e2REYJWRj7MkGevsSSy\nb1kCXLt6tKGWAb7lt5c0xyJgUIJW7pdtnwgT0ZCa24BecCAwNnG5U2EwQbcjZGsFxqNGfaemd3oFEhES\nBaE0Fxms9UKTnMafu8wvZ2xymMrUduuRzOjDeX7oD5YsLC88V8CGMLxbbxIpt94KGykbr6e7L0R4oZl1\ntKMgFwQ2p9Txdbp0Y293LcsJymKizqI0F2xEp7y4SmWOJqHZtsbz80wVV9nv41CvtfxuSoGZJ5cNB7pI\nBgzNcQCeH3Jt0RaGGwboxxpuFbzilmkMFXxJm87tD4WNgu01nHfGCKeQcySEBZpVfJgi6sDFJ8uWnvKm\n9mPLHurtWzEfKqUEa1iC71bXjw5wrvhv9BYW8JSUELHmDquftQyKdq0DZXhULMHGQLf4e95WIaoA14LL\nbThz77kuhKULPTu2MNrBUKGorurhGugo5gs4ZUezSsUOe3KxYdrFMdGgny1GgTxMSMTp2RAZytKjv4kQ\nVx7XgzvpQLIbDjUPAkJv6lScwIRq1W3Ne0Rh0V6Bmn6U5uIuWnJjULmbaQiSODj3z0mAZvak0mSWIGwT\nTX83HztcC4W7e1f6a1thmcc5K61Icehla2hBELWPpixTkyC4eEVmk9Rq0m0ZXtx0JX2ZQXqXDEyePyMe\nJ70sdSzXk72zusqhY4yuOMGgbYNHqxOToK6NxujR7e4dV3Wk5JnSUthym8scjcPeCiKDNY4cHfTMnDXJ\n9zLVy01LtNKYpJ1s8FxVxigmxQNKEbIamxhx6yqwGC4aiISVOOUEjvNOdaUfXfUsE6jEwtwxyGxjlRK1\ncLyxXttq4QWN6PehgHv7jXykzPjInbEysebFvvPOOMdunmJvcCNMSvjUda8fL6xfGo0FDrLg8XZipd6S\noPVdYtyIM1Dg40KbBA3JuumPYtXuJaHrZnjZmdnM5OVo4ZNxktfCVT0c6bnD4bAeyn4bYt1ZPaX6hQHh\nJtvNYfpD0ONYlmqKuToQAMlz52Fh6bj45EbX89L5eLlSpWeyBlGotzriB0EPlclrGi5l2B5oPb1aB1ag\nyyYuu44l0F1oOVYnBIZsxIsHVITxi9lEuVPFkWASOUNuVQXfM4n5hxWR9qtuKnIcPsvbJsv1U10XlKh3\nKisqPhHU15xrCLr5gwFxPUKiNTLUBrkzgBOHXPVsHcLCiSD0YU56TRGfvEom43TWUKPPfl9Z54tgVQuT\njCRlaljAzeniQIcbbHZnn3f0HxbDG3DFYqWSxNrXabHhRsIOhhUHSPENyhGSTVO5t0XX5CdMspJPCd02\n3Oqv32ccbUK4O3YH6LEvp0WO3kSl5n50odVkI9B0i0iq4UPFGMkM8bEQJbgJoOH71P10vtdevJFQE4g2\nyhimiM53ZJRWgSZveHtENZc0Gjo0F9eioak9BnPpY1QxAFPC817svuhEstcU69bLCA4D1rO5R8AuIIBq\nyQJcifFLvbpAEYTLKJqysZrU8EEl3TSdC13A9hZvk4NC8VGEDAxcNrKw313dZp17kZPO5HSd1y6sljAW\nA9M1d6FMYV5SlBWf3WZNCUPS7qKNlda2YBsC6IUVB363f5RLGQOQHwbaijBSRCkrVoRxBHtc0Bd5J9V9\nP5uMTXkpZOxRcCQvImGgcmGuxxLb5zTqfS2xu7v3Sf3IIesSt9tVzcEcdbEvLGVJkLk4mb3G30DbIbri\nPZ09JkweDvMaQ3bxT2nfkz3Ilihkw9jqikkCCCz7E8h6z6KbhQErEW9VzJZzMCgJsyPjFam6iNwpe07S\nhyOvNVw2t9wpzL5xM11DvVzQwDaWEytNRHzDBs4KwEtpI2IpjUyVZHSwA0UGqqkzoCgrJFlNOvPlXqcS\nIcREouUIBmuttkrhPWJtSxOOgpsdvBR3kTOzAXNzSKxoaBAb0c5SDMUc6FIyGA8x5wg5DkUgjFUUodEt\nOYaB2VHVePW9mxHeBTdKWLzJow4ZZvjnoBuVigXljKCNh137ckV2y3Yg3Xi4UzJEI2V5Rw9AfnMs7xUw\nVHOFCg189maD3bmZAe7b4eaGZhyy4HVKjqCXmIH7vsEjRvbnfB0SQxxpuqBDJbHNCtW4vM643ZQQBVPP\na7oXSQIq9w2dHp0A7dtkocCZdQp9FKR9XdJAFIbVSHzIF1ZogeZlc0pXuNE0tagvD57xwDRFkAuoQyMu\nYDdZasXrpSmEE5UjHVkyYsISn8QsfXurzDybX468aoRoks654jjmRY5zi1oB8TcMdC2c3sicNaqfeuhd\nH1nPX7l4RpdqWMR7gGx9slXtG8S3KxpOi4qCD7yg3saD66nun4dzksQURoTUdXyrJR5UpHsfIlTF1aJa\nMdXyQtQnrkl00TeghQd00rRFZsCnhi0qrCSKiBfB2EVrd9RPpbgwJGZHuIQecdBmNetc2ylSEClqVBPR\nGOPPIxrnswEZjmnS0jxKW9VSM1QVxSPJnPFswCqT95SoKD6CP4xdX28WIUGiNaIKodXXJHEIsXBCxLsr\nPwWPCtoplC6hhpKmW5dQo92iCTyY2KioKzO8XR6FKm6qonMKVEwQNtlYE9c97KMtEnp25VOdMP46SQXS\nYsSVp7vm8LP87VYI8SOKcW3s2oedYFtt45rvDzoTF0GmS6wELQ9uo98HhjQAI1Dt91cgjJOwygNmLoZE\nX5K2zQiNA163uMCl5xzaBqY4YTL0wgALg3IFdYSp0RFYLWdt6IxoGI1tnoxcjlUEPo5eGIc3mS3SmaLn\nOdumfUQQ4Jgmgaa5anUVQsfBDrlAN5oaX7O0JO71SSPSWiHBsT9WIPy2J1Cace9ZZLRxblFPSXcvsuHh\nhvnhWQltEDAe7MgvkFQ8lGVFa8jhzijoF9kLmMhMILSzYnfXnZPNP7TlAAwlLHK1RqlpHskJqb6CPpGP\nQvOAhEMsM3zJ2KejZx0esxkjxA0ZufVvGAMN3vTUMplQaF4RiQkp9fzBXf3CMk01dWjOMMIEXTeKzIQe\nEcffzjixWU9FpAyGp2rVl4ETRgqljOGw4UgK31r0ZIEGnH0xGz1FtbW1OcQM008JVujRqulCucEMmntr\n" + ) + + try: + await client.put_with_content_encoding(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/requestcompression/putcontentwithencoding" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-encoding", "gzip")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_sdk_appended_gzip_after_provided_encoding_rest_json1_request_put_with_content_encoding() -> ( + None +): + """ + Compression algorithm encoding is appended to the Content-Encoding + header, and the user-provided content-encoding is in the + Content-Encoding header before the request compression encoding from the + HTTP binding. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = PutWithContentEncodingInput( + encoding="custom", + data="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\n", + ) + + try: + await client.put_with_content_encoding(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/requestcompression/putcontentwithencoding" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-encoding", "custom, gzip")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_query_idempotency_token_auto_fill_request_query_idempotency_token_auto_fill() -> ( + None +): + """Automatically adds idempotency token when not set""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryIdempotencyTokenAutoFillInput() + + try: + await client.query_idempotency_token_auto_fill(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/QueryIdempotencyTokenAutoFill" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [ + "token=00000000-0000-4000-8000-000000000000" + ] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_query_idempotency_token_auto_fill_is_set_request_query_idempotency_token_auto_fill() -> ( + None +): + """Uses the given idempotency token as-is""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryIdempotencyTokenAutoFillInput( + token="00000000-0000-4000-8000-000000000000" + ) + + try: + await client.query_idempotency_token_auto_fill(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/QueryIdempotencyTokenAutoFill" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [ + "token=00000000-0000-4000-8000-000000000000" + ] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_query_params_string_list_map_request_query_params_as_string_list_map() -> ( + None +): + """Serialize query params from map of list strings""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryParamsAsStringListMapInput(qux="named", foo={"baz": ["bar", "qux"]}) + + try: + await client.query_params_as_string_list_map(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/StringListMap" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["corge=named", "baz=bar", "baz=qux"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_query_precedence_request_query_precedence() -> None: + """Prefer named query parameters when serializing""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = QueryPrecedenceInput( + foo="named", baz={"bar": "fromMap", "qux": "alsoFromMap"} + ) + + try: + await client.query_precedence(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/Precedence" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = ["bar=named", "qux=alsoFromMap"] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_recursive_shapes_request_recursive_shapes() -> None: + """Serializes recursive structures""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = RecursiveShapesInput( + nested=RecursiveShapesInputOutputNested1( + foo="Foo1", + nested=RecursiveShapesInputOutputNested2( + bar="Bar1", + recursive_member=RecursiveShapesInputOutputNested1( + foo="Foo2", nested=RecursiveShapesInputOutputNested2(bar="Bar2") + ), + ), + ) + ) + + try: + await client.recursive_shapes(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/RecursiveShapes" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "nested": {\n "foo": "Foo1",\n "nested": {\n "bar": "Bar1",\n "recursiveMember": {\n "foo": "Foo2",\n "nested": {\n "bar": "Bar2"\n }\n }\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_recursive_shapes_response_recursive_shapes() -> None: + """Serializes recursive structures""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "nested": {\n "foo": "Foo1",\n "nested": {\n "bar": "Bar1",\n "recursiveMember": {\n "foo": "Foo2",\n "nested": {\n "bar": "Bar2"\n }\n }\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = RecursiveShapesInput() + + try: + actual = await client.recursive_shapes(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = RecursiveShapesOutput( + nested=RecursiveShapesInputOutputNested1( + foo="Foo1", + nested=RecursiveShapesInputOutputNested2( + bar="Bar1", + recursive_member=RecursiveShapesInputOutputNested1( + foo="Foo2", nested=RecursiveShapesInputOutputNested2(bar="Bar2") + ), + ), + ) + ) + + assert actual == expected + + +async def test_rest_json_simple_scalar_properties_request_simple_scalar_properties() -> ( + None +): + """Serializes simple scalar properties""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + foo="Foo", + string_value="string", + true_boolean_value=True, + false_boolean_value=False, + byte_value=1, + short_value=2, + integer_value=3, + long_value=4, + float_value=float(5.5), + double_value=float(6.5), + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/SimpleScalarProperties" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/json"), + ("x-foo", "Foo"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "stringValue": "string",\n "trueBooleanValue": true,\n "falseBooleanValue": false,\n "byteValue": 1,\n "shortValue": 2,\n "integerValue": 3,\n "longValue": 4,\n "floatValue": 5.5,\n "DoubleDribble": 6.5\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_doesnt_serialize_null_structure_values_request_simple_scalar_properties() -> ( + None +): + """Rest Json should not serialize null structure values""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput(string_value=None) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/SimpleScalarProperties" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_supports_na_n_float_inputs_request_simple_scalar_properties() -> ( + None +): + """Supports handling NaN float values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + float_value=float("nan"), double_value=float("nan") + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/SimpleScalarProperties" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "floatValue": "NaN",\n "DoubleDribble": "NaN"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_infinity_float_inputs_request_simple_scalar_properties() -> ( + None +): + """Supports handling Infinity float values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + float_value=float("inf"), double_value=float("inf") + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/SimpleScalarProperties" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "floatValue": "Infinity",\n "DoubleDribble": "Infinity"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_supports_negative_infinity_float_inputs_request_simple_scalar_properties() -> ( + None +): + """Supports handling -Infinity float values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput( + float_value=float("-inf"), double_value=float("-inf") + ) + + try: + await client.simple_scalar_properties(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/SimpleScalarProperties" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = ( + b'{\n "floatValue": "-Infinity",\n "DoubleDribble": "-Infinity"\n}' + ) + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_simple_scalar_properties_response_simple_scalar_properties() -> ( + None +): + """Serializes simple scalar properties""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json"), ("X-Foo", "Foo")], + body=b'{\n "stringValue": "string",\n "trueBooleanValue": true,\n "falseBooleanValue": false,\n "byteValue": 1,\n "shortValue": 2,\n "integerValue": 3,\n "longValue": 4,\n "floatValue": 5.5,\n "DoubleDribble": 6.5\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + foo="Foo", + string_value="string", + true_boolean_value=True, + false_boolean_value=False, + byte_value=1, + short_value=2, + integer_value=3, + long_value=4, + float_value=float(5.5), + double_value=float(6.5), + ) + + assert actual == expected + + +async def test_rest_json_doesnt_deserialize_null_structure_values_response_simple_scalar_properties() -> ( + None +): + """Rest Json should not deserialize null structure values""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "stringValue": null\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput() + + assert actual == expected + + +@mark.xfail() +async def test_rest_json_supports_na_n_float_inputs_response_simple_scalar_properties() -> ( + None +): + """Supports handling NaN float values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "floatValue": "NaN",\n "DoubleDribble": "NaN"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + float_value=float("nan"), double_value=float("nan") + ) + + assert actual == expected + + +async def test_rest_json_supports_infinity_float_inputs_response_simple_scalar_properties() -> ( + None +): + """Supports handling Infinity float values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "floatValue": "Infinity",\n "DoubleDribble": "Infinity"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + float_value=float("inf"), double_value=float("inf") + ) + + assert actual == expected + + +async def test_rest_json_supports_negative_infinity_float_inputs_response_simple_scalar_properties() -> ( + None +): + """Supports handling -Infinity float values.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "floatValue": "-Infinity",\n "DoubleDribble": "-Infinity"\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SimpleScalarPropertiesInput() + + try: + actual = await client.simple_scalar_properties(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SimpleScalarPropertiesOutput( + float_value=float("-inf"), double_value=float("-inf") + ) + + assert actual == expected + + +async def test_rest_json_sparse_lists_serialize_null_request_sparse_json_lists() -> ( + None +): + """Serializes null values in sparse lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonListsInput( + sparse_string_list=[None, "hi"], sparse_short_list=[None, 2] + ) + + try: + await client.sparse_json_lists(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "PUT" + assert actual.destination.path == "/SparseJsonLists" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "sparseStringList": [\n null,\n "hi"\n ],\n "sparseShortList": [\n null,\n 2\n ]\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_sparse_lists_serialize_null_response_sparse_json_lists() -> ( + None +): + """Serializes null values in sparse lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "sparseStringList": [\n null,\n "hi"\n ],\n "sparseShortList": [\n null,\n 2\n ]\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonListsInput() + + try: + actual = await client.sparse_json_lists(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SparseJsonListsOutput( + sparse_string_list=[None, "hi"], sparse_short_list=[None, 2] + ) + + assert actual == expected + + +async def test_rest_json_sparse_json_maps_request_sparse_json_maps() -> None: + """Serializes JSON maps""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput( + sparse_struct_map={ + "foo": GreetingStruct(hi="there"), + "baz": GreetingStruct(hi="bye"), + } + ) + + try: + await client.sparse_json_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/SparseJsonMaps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "sparseStructMap": {\n "foo": {\n "hi": "there"\n },\n "baz": {\n "hi": "bye"\n }\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serializes_sparse_null_map_values_request_sparse_json_maps() -> ( + None +): + """Serializes JSON map values in sparse maps""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput( + sparse_struct_map={"x": None}, + sparse_number_map={"x": None}, + sparse_boolean_map={"x": None}, + sparse_string_map={"x": None}, + ) + + try: + await client.sparse_json_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/SparseJsonMaps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "sparseBooleanMap": {\n "x": null\n },\n "sparseNumberMap": {\n "x": null\n },\n "sparseStringMap": {\n "x": null\n },\n "sparseStructMap": {\n "x": null\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serializes_zero_values_in_sparse_maps_request_sparse_json_maps() -> ( + None +): + """Ensure that 0 and false are sent over the wire in all maps and lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput( + sparse_number_map={"x": 0}, sparse_boolean_map={"x": False} + ) + + try: + await client.sparse_json_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/SparseJsonMaps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "sparseNumberMap": {\n "x": 0\n },\n "sparseBooleanMap": {\n "x": false\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serializes_sparse_set_map_request_sparse_json_maps() -> None: + """A request that contains a sparse map of sets""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput(sparse_set_map={"x": [], "y": ["a", "b"]}) + + try: + await client.sparse_json_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/SparseJsonMaps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "sparseSetMap": {\n "x": [],\n "y": ["a", "b"]\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_serializes_sparse_set_map_and_retains_null_request_sparse_json_maps() -> ( + None +): + """A request that contains a sparse map of sets.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput(sparse_set_map={"x": [], "y": ["a", "b"], "z": None}) + + try: + await client.sparse_json_maps(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/SparseJsonMaps" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{\n "sparseSetMap": {\n "x": [],\n "y": ["a", "b"],\n "z": null\n }\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_sparse_json_maps_response_sparse_json_maps() -> None: + """Deserializes JSON maps""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "sparseStructMap": {\n "foo": {\n "hi": "there"\n },\n "baz": {\n "hi": "bye"\n }\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput() + + try: + actual = await client.sparse_json_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SparseJsonMapsOutput( + sparse_struct_map={ + "foo": GreetingStruct(hi="there"), + "baz": GreetingStruct(hi="bye"), + } + ) + + assert actual == expected + + +async def test_rest_json_deserializes_sparse_null_map_values_response_sparse_json_maps() -> ( + None +): + """Deserializes null JSON map values""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "sparseBooleanMap": {\n "x": null\n },\n "sparseNumberMap": {\n "x": null\n },\n "sparseStringMap": {\n "x": null\n },\n "sparseStructMap": {\n "x": null\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput() + + try: + actual = await client.sparse_json_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SparseJsonMapsOutput( + sparse_struct_map={"x": None}, + sparse_number_map={"x": None}, + sparse_boolean_map={"x": None}, + sparse_string_map={"x": None}, + ) + + assert actual == expected + + +async def test_rest_json_deserializes_zero_values_in_sparse_maps_response_sparse_json_maps() -> ( + None +): + """Ensure that 0 and false are sent over the wire in all maps and lists""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "sparseNumberMap": {\n "x": 0\n },\n "sparseBooleanMap": {\n "x": false\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput() + + try: + actual = await client.sparse_json_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SparseJsonMapsOutput( + sparse_number_map={"x": 0}, sparse_boolean_map={"x": False} + ) + + assert actual == expected + + +async def test_rest_json_deserializes_sparse_set_map_response_sparse_json_maps() -> ( + None +): + """A response that contains a sparse map of sets""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "sparseSetMap": {\n "x": [],\n "y": ["a", "b"]\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput() + + try: + actual = await client.sparse_json_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SparseJsonMapsOutput(sparse_set_map={"x": [], "y": ["a", "b"]}) + + assert actual == expected + + +async def test_rest_json_deserializes_sparse_set_map_and_retains_null_response_sparse_json_maps() -> ( + None +): + """A response that contains a sparse map of sets.""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "application/json")], + body=b'{\n "sparseSetMap": {\n "x": [],\n "y": ["a", "b"],\n "z": null\n }\n}', + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = SparseJsonMapsInput() + + try: + actual = await client.sparse_json_maps(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = SparseJsonMapsOutput( + sparse_set_map={"x": [], "y": ["a", "b"], "z": None} + ) + + assert actual == expected + + +async def test_rest_json_streaming_traits_with_blob_request_streaming_traits() -> None: + """Serializes a blob in the HTTP payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = StreamingTraitsInput(foo="Foo", blob=b"blobby blob blob") + + try: + await client.streaming_traits(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/StreamingTraits" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/octet-stream"), + ("x-foo", "Foo"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"blobby blob blob" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_streaming_traits_with_no_blob_body_request_streaming_traits() -> ( + None +): + """Serializes an empty blob in the HTTP payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = StreamingTraitsInput(foo="Foo") + + try: + await client.streaming_traits(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/StreamingTraits" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("x-foo", "Foo")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_streaming_traits_with_blob_response_streaming_traits() -> None: + """Serializes a blob in the HTTP payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[ + ("Content-Type", "application/octet-stream"), + ("X-Foo", "Foo"), + ], + body=b"blobby blob blob", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = StreamingTraitsInput() + + try: + actual = await client.streaming_traits(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = StreamingTraitsOutput(foo="Foo", blob=b"blobby blob blob") + + assert actual.foo == expected.foo + + assert isinstance(actual.blob, AsyncByteStream) + actual_body_content = await actual.blob.read() + expected_body_content = await AsyncBytesReader(expected.blob).read() + + assert actual_body_content == expected_body_content + + +async def test_rest_json_streaming_traits_with_no_blob_body_response_streaming_traits() -> ( + None +): + """Serializes an empty blob in the HTTP payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, headers=[("X-Foo", "Foo")], body=b"" + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = StreamingTraitsInput() + + try: + actual = await client.streaming_traits(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = StreamingTraitsOutput(foo="Foo", blob=b"") + + assert actual.foo == expected.foo + + assert isinstance(actual.blob, AsyncByteStream) + actual_body_content = await actual.blob.read() + expected_body_content = await AsyncBytesReader(expected.blob).read() + + assert actual_body_content == expected_body_content + + +async def test_rest_json_streaming_traits_require_length_with_blob_request_streaming_traits_require_length() -> ( + None +): + """Serializes a blob in the HTTP payload with a required length""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = StreamingTraitsRequireLengthInput(foo="Foo", blob=b"blobby blob blob") + + try: + await client.streaming_traits_require_length(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/StreamingTraitsRequireLength" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/octet-stream"), + ("x-foo", "Foo"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"blobby blob blob" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_streaming_traits_require_length_with_no_blob_body_request_streaming_traits_require_length() -> ( + None +): + """Serializes an empty blob in the HTTP payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = StreamingTraitsRequireLengthInput(foo="Foo") + + try: + await client.streaming_traits_require_length(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/StreamingTraitsRequireLength" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("x-foo", "Foo")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_streaming_traits_with_media_type_with_blob_request_streaming_traits_with_media_type() -> ( + None +): + """Serializes a blob in the HTTP payload with a content-type""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = StreamingTraitsWithMediaTypeInput(foo="Foo", blob=b"blobby blob blob") + + try: + await client.streaming_traits_with_media_type(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/StreamingTraitsWithMediaType" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "text/plain"), + ("x-foo", "Foo"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"blobby blob blob" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_streaming_traits_with_media_type_with_blob_response_streaming_traits_with_media_type() -> ( + None +): + """Serializes a blob in the HTTP payload with a content-type""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[("Content-Type", "text/plain"), ("X-Foo", "Foo")], + body=b"blobby blob blob", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = StreamingTraitsWithMediaTypeInput() + + try: + actual = await client.streaming_traits_with_media_type(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = StreamingTraitsWithMediaTypeOutput( + foo="Foo", blob=b"blobby blob blob" + ) + + assert actual.foo == expected.foo + + assert isinstance(actual.blob, AsyncByteStream) + actual_body_content = await actual.blob.read() + expected_body_content = await AsyncBytesReader(expected.blob).read() + + assert actual_body_content == expected_body_content + + +async def test_rest_json_test_body_structure_request_test_body_structure() -> None: + """Serializes a structure""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestBodyStructureInput(test_config=TestConfig(timeout=10)) + + try: + await client.test_body_structure(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/body" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"testConfig":\n {"timeout": 10}\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_with_empty_body_request_test_body_structure() -> None: + """Serializes an empty structure in the body""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestBodyStructureInput() + + try: + await client.test_body_structure(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/body" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_get_with_no_input_request_test_get_no_input_no_payload() -> ( + None +): + """ + Serializes a GET request for an operation with no input, and therefore + no modeled body + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestGetNoInputNoPayloadInput() + + try: + await client.test_get_no_input_no_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/no_input_no_payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set(["content-type", "content-length"]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_get_with_no_modeled_body_request_test_get_no_payload() -> ( + None +): + """Serializes a GET request with no modeled body""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestGetNoPayloadInput() + + try: + await client.test_get_no_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/no_payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set(["content-length", "content-type"]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_get_with_header_member_no_modeled_body_request_test_get_no_payload() -> ( + None +): + """Serializes a GET request with header member but no modeled body""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestGetNoPayloadInput(test_id="t-12345") + + try: + await client.test_get_no_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "GET" + assert actual.destination.path == "/no_payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("x-amz-test-id", "t-12345")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set(["content-length", "content-type"]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_with_empty_blob_payload_request_test_payload_blob() -> ( + None +): + """Serializes a payload targeting an empty blob""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestPayloadBlobInput() + + try: + await client.test_payload_blob(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/blob_payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_test_payload_blob_request_test_payload_blob() -> None: + """Serializes a payload targeting a blob""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestPayloadBlobInput(content_type="image/jpg", data=b"1234") + + try: + await client.test_payload_blob(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/blob_payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "image/jpg")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"1234" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_http_with_empty_structure_payload_request_test_payload_structure() -> ( + None +): + """Serializes a payload targeting an empty structure""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestPayloadStructureInput() + + try: + await client.test_payload_structure(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_test_payload_structure_request_test_payload_structure() -> ( + None +): + """Serializes a payload targeting a structure""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestPayloadStructureInput(payload_config=PayloadConfig(data=25)) + + try: + await client.test_payload_structure(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("content-type", "application/json")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b'{"data": 25\n}' + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +@mark.xfail() +async def test_rest_json_http_with_headers_but_no_payload_request_test_payload_structure() -> ( + None +): + """Serializes an request with header members but no payload""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestPayloadStructureInput(test_id="t-12345") + + try: + await client.test_payload_structure(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("content-type", "application/json"), + ("x-amz-test-id", "t-12345"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = ["content-length"] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"{}" + actual_body = json.loads(actual_body_content) if actual_body_content else "" + expected_body = json.loads(expected_body_content) + assert actual_body == expected_body + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_post_with_no_input_request_test_post_no_input_no_payload() -> ( + None +): + """ + Serializes a POST request for an operation with no input, and therefore + no modeled body + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestPostNoInputNoPayloadInput() + + try: + await client.test_post_no_input_no_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/no_input_no_payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set(["content-type"]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_post_with_no_modeled_body_request_test_post_no_payload() -> ( + None +): + """Serializes a POST request with no modeled body""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestPostNoPayloadInput() + + try: + await client.test_post_no_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/no_payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set(["content-type"]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_http_with_post_header_member_no_modeled_body_request_test_post_no_payload() -> ( + None +): + """Serializes a POST request with header member but no modeled body""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TestPostNoPayloadInput(test_id="t-12345") + + try: + await client.test_post_no_payload(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/no_payload" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [("x-amz-test-id", "t-12345")] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set(["content-type"]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_timestamp_format_headers_request_timestamp_format_headers() -> ( + None +): + """Tests how timestamp request headers are serialized""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TimestampFormatHeadersInput( + member_epoch_seconds=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + member_http_date=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + member_date_time=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + default_format=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + target_epoch_seconds=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + target_http_date=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + target_date_time=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + ) + + try: + await client.timestamp_format_headers(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/TimestampFormatHeaders" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [ + ("x-defaultformat", "Mon, 16 Dec 2019 23:48:18 GMT"), + ("x-memberdatetime", "2019-12-16T23:48:18Z"), + ("x-memberepochseconds", "1576540098"), + ("x-memberhttpdate", "Mon, 16 Dec 2019 23:48:18 GMT"), + ("x-targetdatetime", "2019-12-16T23:48:18Z"), + ("x-targetepochseconds", "1576540098"), + ("x-targethttpdate", "Mon, 16 Dec 2019 23:48:18 GMT"), + ] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_timestamp_format_headers_response_timestamp_format_headers() -> ( + None +): + """Tests how timestamp response headers are serialized""" + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient( + status=200, + headers=[ + ("X-defaultFormat", "Mon, 16 Dec 2019 23:48:18 GMT"), + ("X-memberDateTime", "2019-12-16T23:48:18Z"), + ("X-memberEpochSeconds", "1576540098"), + ("X-memberHttpDate", "Mon, 16 Dec 2019 23:48:18 GMT"), + ("X-targetDateTime", "2019-12-16T23:48:18Z"), + ("X-targetEpochSeconds", "1576540098"), + ("X-targetHttpDate", "Mon, 16 Dec 2019 23:48:18 GMT"), + ], + body=b"", + ), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = TimestampFormatHeadersInput() + + try: + actual = await client.timestamp_format_headers(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = TimestampFormatHeadersOutput( + member_epoch_seconds=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + member_http_date=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + member_date_time=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + default_format=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + target_epoch_seconds=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + target_http_date=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + target_date_time=datetime(2019, 12, 16, 23, 48, 18, 0, timezone.utc), + ) + + assert actual == expected + + +async def test_rest_json_unit_input_and_output_request_unit_input_and_output() -> None: + """ + A unit type input serializes no payload. When clients do not need to + serialize any data in the payload, they should omit a payload + altogether. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com/", + transport=RequestTestHTTPClient(), + retry_strategy=SimpleRetryStrategy(max_attempts=1), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = UnitInputAndOutputInput() + + try: + await client.unit_input_and_output(input_) + fail("Expected 'TestHttpServiceError' exception to be thrown!") + except TestHttpServiceError as err: + actual = err.request + + assert actual.method == "POST" + assert actual.destination.path == "/UnitInputAndOutput" + assert actual.destination.host == "example.com" + + query = actual.destination.query + actual_query_segments: list[str] = query.split("&") if query else [] + expected_query_segments: list[str] = [] + for expected_query_segment in expected_query_segments: + assert expected_query_segment in actual_query_segments + actual_query_segments.remove(expected_query_segment) + + actual_query_keys: list[str] = [k.lower() for k, v in parse_qsl(query)] + forbidden_query_keys: set[str] = set([]) + for forbidden_key in forbidden_query_keys: + assert forbidden_key.lower() not in actual_query_keys + + required_query_keys: list[str] = [] + for required_query_key in required_query_keys: + assert required_query_key.lower() in actual_query_keys + # These are removed because the required list could require more than one + # value. By removing each value after we assert that it's there, we can + # effectively validate that without having to have a more complex comparator. + actual_query_keys.remove(required_query_key) + + expected_headers: list[tuple[str, str]] = [] + for expected_key, expected_val in expected_headers: + assert expected_val in actual.fields[expected_key].values + + forbidden_headers: set[str] = set([]) + for forbidden_key in forbidden_headers: + with raises(KeyError): + actual.fields[forbidden_key] + + required_headers: list[str] = [] + for required_key in required_headers: + # del Fields[required_key] raises KeyError if key does not exist + del actual.fields[required_key] + + actual_body_content = await AsyncBytesReader(actual.body or b"").read() + expected_body_content = b"" + assert actual_body_content == expected_body_content + + except Exception as err: + fail( + f"Expected 'TestHttpServiceError' exception to be thrown, but received {type(err).__name__}: {err}" + ) + + +async def test_rest_json_unit_input_and_output_no_output_response_unit_input_and_output() -> ( + None +): + """ + When an operation defines Unit output, the service will respond with an + empty payload, and may optionally include the content-type header. + """ + client = AsyncRestJsonProtocolClient( + config=await AsyncRestJsonProtocolConfig.resolve( + endpoint_uri="https://example.com", + transport=ResponseTestHTTPClient(status=200, headers=[], body=b""), + region="us-east-1", + aws_access_key_id="test-access-key-id", + aws_secret_access_key="test-secret-access-key", + aws_credentials_identity_resolver=StaticCredentialsResolver(), + ) + ) + + input_ = UnitInputAndOutputInput() + + try: + actual = await client.unit_input_and_output(input_) + except Exception as err: + fail(f"Expected a valid response, but received: {type(err).__name__}: {err}") + else: + expected = UnitInputAndOutputOutput() + + assert actual == expected + + +class TestHttpServiceError(ServiceError): + """A test error that subclasses the service-error for protocol tests.""" + + def __init__(self, request: HTTPRequest): + self.request = request + + +class RequestTestHTTPClient: + """An asynchronous HTTP client solely for testing purposes.""" + + TIMEOUT_EXCEPTIONS = () + SUPPORTS_DUPLEX_STREAMING: bool = True + + def __init__(self, *, client_config: HTTPClientConfiguration | None = None): + self._client_config = client_config + + async def send( + self, + request: HTTPRequest, + *, + request_config: HTTPRequestConfiguration | None = None, + ) -> _smithy_http_aio_interfaces_HTTPResponse: + # Raise the exception with the request object to bypass actual request handling + raise TestHttpServiceError(request) + + +class ResponseTestHTTPClient: + """An asynchronous HTTP client solely for testing purposes.""" + + TIMEOUT_EXCEPTIONS = () + SUPPORTS_DUPLEX_STREAMING: bool = True + + def __init__( + self, + *, + client_config: HTTPClientConfiguration | None = None, + status: int = 200, + headers: list[tuple[str, str]] | None = None, + body: bytes = b"", + ): + self._client_config = client_config + self.status = status + self.fields = tuples_to_fields(headers or []) + self.body = body + + async def send( + self, + request: HTTPRequest, + *, + request_config: HTTPRequestConfiguration | None = None, + ) -> _smithy_http_aio_HTTPResponse: + # Pre-construct the response from the request and return it + return _smithy_http_aio_HTTPResponse( + status=self.status, fields=self.fields, body=async_list([self.body]) + ) diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/SchemaGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/SchemaGenerator.java index ac6bd4657..a06e61196 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/SchemaGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/generators/SchemaGenerator.java @@ -5,11 +5,12 @@ package software.amazon.smithy.python.codegen.generators; import java.util.Collection; -import java.util.HashMap; +import java.util.Comparator; import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.TreeMap; import java.util.function.Consumer; import java.util.function.Function; import java.util.logging.Logger; @@ -58,7 +59,8 @@ public final class SchemaGenerator implements Consumer { private final GenerationContext context; private final Set generatedShapes = new HashSet<>(); - private final Map deferredMembers = new HashMap<>(); + private final Map deferredMembers = + new TreeMap<>(Comparator.comparing(MemberShape::getId)); public SchemaGenerator(GenerationContext context) { this.context = context;