From 12798836566f0df86aabf850d3863b6a2e049c6d Mon Sep 17 00:00:00 2001 From: SamRemis Date: Wed, 9 Apr 2025 11:31:07 -0400 Subject: [PATCH 1/7] Add OperationSection to event stream operation generation Add documentation generation to event stream operations --- .../software/amazon/smithy/python/codegen/ClientGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java index a1c8abbe0..8e8b4fb49 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java @@ -905,7 +905,7 @@ private void writeSharedOperationInit(PythonWriter writer, OperationShape operat } private void generateEventStreamOperation(PythonWriter writer, OperationShape operation) { - writer.pushState(); + writer.pushState(new OperationSection(service, operation)); writer.addDependency(SmithyPythonDependency.SMITHY_CORE); var operationSymbol = symbolProvider.toSymbol(operation); writer.putContext("operation", operationSymbol); From 92c95d5abe841f99c040f8ea687f2f226df4157d Mon Sep 17 00:00:00 2001 From: SamRemis Date: Wed, 9 Apr 2025 13:57:43 -0400 Subject: [PATCH 2/7] Handle stream wrapper classes --- .../python/aws/codegen/AwsRstDocFileGenerator.java | 10 ++++++++-- .../amazon/smithy/python/codegen/ClientGenerator.java | 4 ++-- .../python/codegen/sections/OperationSection.java | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java index 0141801b3..d90da45de 100644 --- a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java +++ b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java @@ -69,7 +69,8 @@ public void append(PythonWriter pythonWriter, OperationSection section) { String operationName = operationSymbol.getName(); String inputSymbolName = inputSymbol.toString(); - String outputSymbolName = outputSymbol.toString(); + String outputSymbolName = outputSymbol.toString().replace("OperationOutput", + "Output"); String serviceName = context.symbolProvider().toSymbol(section.service()).getName(); String docsFileName = String.format("docs/client/%s.rst", operationName); String fullOperationReference = String.format("%s.client.%s.%s", @@ -109,7 +110,12 @@ public void append(PythonWriter pythonWriter, StructureSection section) { var symbol = context.symbolProvider().toSymbol(shape); String docsFileName = String.format("docs/models/%s.rst", symbol.getName()); - if (!shape.hasTrait(InputTrait.class) && !shape.hasTrait(OutputTrait.class)) { + // Generally we want to skip input and output shapes because those will + // be generated on the operation's page; if it ends with + // "OperationOutput", that suggests it's a wrapper around the standard + // output shape. In this case we want to document it since the streaming + // class documents the wrapped class. + if (!shape.hasTrait(InputTrait.class) && !shape.hasTrait(OutputTrait.class) || symbol.getName().endsWith("OperationOutput")) { context.writerDelegator().useFileWriter(docsFileName, "", writer -> { writer.write(generateHeader(symbol.getName())); writer.write(".. autoclass:: " + symbol.toString() + "\n :members:\n"); diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java index 8e8b4fb49..daca99e19 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java @@ -830,7 +830,7 @@ private void generateOperation(PythonWriter writer, OperationShape operation) { var output = model.expectShape(operation.getOutputShape()); var outputSymbol = symbolProvider.toSymbol(output); - writer.pushState(new OperationSection(service, operation)); + writer.pushState(new OperationSection(service, operation, false)); writer.openBlock("async def $L(self, input: $T, plugins: list[$T] | None = None) -> $T:", "", operationMethodSymbol.getName(), @@ -905,7 +905,7 @@ private void writeSharedOperationInit(PythonWriter writer, OperationShape operat } private void generateEventStreamOperation(PythonWriter writer, OperationShape operation) { - writer.pushState(new OperationSection(service, operation)); + writer.pushState(new OperationSection(service, operation, true)); writer.addDependency(SmithyPythonDependency.SMITHY_CORE); var operationSymbol = symbolProvider.toSymbol(operation); writer.putContext("operation", operationSymbol); diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/sections/OperationSection.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/sections/OperationSection.java index ceab19545..05a731d7e 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/sections/OperationSection.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/sections/OperationSection.java @@ -13,4 +13,5 @@ * A section that controls writing an operation. */ @SmithyInternalApi -public record OperationSection(Shape service, OperationShape operation) implements CodeSection {} +public record OperationSection(Shape service, OperationShape operation, + boolean isStream) implements CodeSection {} From 8cd5b2c05f38b19f9a6bf1b5e4cf4973a8e926eb Mon Sep 17 00:00:00 2001 From: SamRemis Date: Wed, 9 Apr 2025 14:30:59 -0400 Subject: [PATCH 3/7] Update AwsRstDocFileGenerator.java --- .../python/aws/codegen/AwsRstDocFileGenerator.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java index d90da45de..e5a79e0ee 100644 --- a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java +++ b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java @@ -69,8 +69,7 @@ public void append(PythonWriter pythonWriter, OperationSection section) { String operationName = operationSymbol.getName(); String inputSymbolName = inputSymbol.toString(); - String outputSymbolName = outputSymbol.toString().replace("OperationOutput", - "Output"); + String outputSymbolName = outputSymbol.toString(); String serviceName = context.symbolProvider().toSymbol(section.service()).getName(); String docsFileName = String.format("docs/client/%s.rst", operationName); String fullOperationReference = String.format("%s.client.%s.%s", @@ -85,7 +84,12 @@ public void append(PythonWriter pythonWriter, OperationSection section) { fileWriter.write("=================\nInput:\n=================\n\n"); fileWriter.write(".. autoclass:: " + inputSymbolName + "\n :members:\n"); fileWriter.write("=================\nOutput:\n=================\n\n"); - fileWriter.write(".. autoclass:: " + outputSymbolName + "\n :members:\n"); + if (section.isStream()) { + String unionShapeName = outputSymbolName.replace("OperationOutput", "Output"); + fileWriter.write(".. autodata:: " + unionShapeName + " \n\n"); + } else { + fileWriter.write(".. autoclass:: " + outputSymbolName + "\n " + ":members:\n\n"); + } }); } } From 2bed14b8508e890994e409e15207395b2fb12fd1 Mon Sep 17 00:00:00 2001 From: SamRemis Date: Wed, 9 Apr 2025 16:23:53 -0400 Subject: [PATCH 4/7] Remove string replace function --- .../aws/codegen/AwsRstDocFileGenerator.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java index e5a79e0ee..371c6159b 100644 --- a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java +++ b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java @@ -85,8 +85,10 @@ public void append(PythonWriter pythonWriter, OperationSection section) { fileWriter.write(".. autoclass:: " + inputSymbolName + "\n :members:\n"); fileWriter.write("=================\nOutput:\n=================\n\n"); if (section.isStream()) { - String unionShapeName = outputSymbolName.replace("OperationOutput", "Output"); - fileWriter.write(".. autodata:: " + unionShapeName + " \n\n"); + var streamShape = + context.model().expectShape(output.getAllMembers().get("stream").getId()); + var streamName = context.symbolProvider().toSymbol(streamShape).toString(); + fileWriter.write(".. autodata:: " + streamName + " \n\n"); } else { fileWriter.write(".. autoclass:: " + outputSymbolName + "\n " + ":members:\n\n"); } @@ -114,11 +116,11 @@ public void append(PythonWriter pythonWriter, StructureSection section) { var symbol = context.symbolProvider().toSymbol(shape); String docsFileName = String.format("docs/models/%s.rst", symbol.getName()); - // Generally we want to skip input and output shapes because those will - // be generated on the operation's page; if it ends with - // "OperationOutput", that suggests it's a wrapper around the standard - // output shape. In this case we want to document it since the streaming - // class documents the wrapped class. + // Input and output shapes are typically skipped since they are generated + // on the operation's page. Shapes ending with "OperationOutput" are + // wrappers around streaming output shapes. These should be documented + // because the streaming class refers to and documents the wrapped class + // and will link to the wrapper class. if (!shape.hasTrait(InputTrait.class) && !shape.hasTrait(OutputTrait.class) || symbol.getName().endsWith("OperationOutput")) { context.writerDelegator().useFileWriter(docsFileName, "", writer -> { writer.write(generateHeader(symbol.getName())); From 51364b68a580d8724b978de230a8ef0fbe08bd76 Mon Sep 17 00:00:00 2001 From: SamRemis Date: Wed, 9 Apr 2025 17:31:50 -0400 Subject: [PATCH 5/7] Remove substring check --- .../aws/codegen/AwsRstDocFileGenerator.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java index 371c6159b..3fe10ca43 100644 --- a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java +++ b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java @@ -7,8 +7,11 @@ import static software.amazon.smithy.python.codegen.SymbolProperties.OPERATION_METHOD; import java.util.List; +import java.util.Optional; + import software.amazon.smithy.model.traits.InputTrait; import software.amazon.smithy.model.traits.OutputTrait; +import software.amazon.smithy.model.traits.StreamingTrait; import software.amazon.smithy.python.codegen.GenerationContext; import software.amazon.smithy.python.codegen.integrations.PythonIntegration; import software.amazon.smithy.python.codegen.sections.*; @@ -116,12 +119,15 @@ public void append(PythonWriter pythonWriter, StructureSection section) { var symbol = context.symbolProvider().toSymbol(shape); String docsFileName = String.format("docs/models/%s.rst", symbol.getName()); + + boolean isStreaming = Optional.ofNullable(shape.getAllMembers().get("body")) + .map(member -> context.model().expectShape(member.getTarget())) + .map(memberShape -> memberShape.hasTrait(StreamingTrait.class)) + .orElse(false); // Input and output shapes are typically skipped since they are generated // Input and output shapes are typically skipped since they are generated - // on the operation's page. Shapes ending with "OperationOutput" are - // wrappers around streaming output shapes. These should be documented - // because the streaming class refers to and documents the wrapped class - // and will link to the wrapper class. - if (!shape.hasTrait(InputTrait.class) && !shape.hasTrait(OutputTrait.class) || symbol.getName().endsWith("OperationOutput")) { + // on the operation's page. The exception to this is the output of + // streaming operations where we have a different output shape defined. + if (!shape.hasTrait(InputTrait.class) && !shape.hasTrait(OutputTrait.class) || isStreaming) { context.writerDelegator().useFileWriter(docsFileName, "", writer -> { writer.write(generateHeader(symbol.getName())); writer.write(".. autoclass:: " + symbol.toString() + "\n :members:\n"); From a06a85fd256fb6d4077fde9ec33511213482465d Mon Sep 17 00:00:00 2001 From: SamRemis Date: Wed, 9 Apr 2025 17:35:22 -0400 Subject: [PATCH 6/7] Update AwsRstDocFileGenerator.java --- .../smithy/python/aws/codegen/AwsRstDocFileGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java index 3fe10ca43..334a16de9 100644 --- a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java +++ b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java @@ -123,7 +123,7 @@ public void append(PythonWriter pythonWriter, StructureSection section) { boolean isStreaming = Optional.ofNullable(shape.getAllMembers().get("body")) .map(member -> context.model().expectShape(member.getTarget())) .map(memberShape -> memberShape.hasTrait(StreamingTrait.class)) - .orElse(false); // Input and output shapes are typically skipped since they are generated + .orElse(false); // Input and output shapes are typically skipped since they are generated // on the operation's page. The exception to this is the output of // streaming operations where we have a different output shape defined. From d264c9f62f55c83b8748f75167a069d280df8b59 Mon Sep 17 00:00:00 2001 From: SamRemis Date: Thu, 10 Apr 2025 18:00:14 -0400 Subject: [PATCH 7/7] revert git changes --- .../aws/codegen/AwsRstDocFileGenerator.java | 22 ++----------------- .../python/codegen/ClientGenerator.java | 4 ++-- .../codegen/sections/OperationSection.java | 3 +-- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java index 334a16de9..0141801b3 100644 --- a/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java +++ b/codegen/aws/core/src/main/java/software/amazon/smithy/python/aws/codegen/AwsRstDocFileGenerator.java @@ -7,11 +7,8 @@ import static software.amazon.smithy.python.codegen.SymbolProperties.OPERATION_METHOD; import java.util.List; -import java.util.Optional; - import software.amazon.smithy.model.traits.InputTrait; import software.amazon.smithy.model.traits.OutputTrait; -import software.amazon.smithy.model.traits.StreamingTrait; import software.amazon.smithy.python.codegen.GenerationContext; import software.amazon.smithy.python.codegen.integrations.PythonIntegration; import software.amazon.smithy.python.codegen.sections.*; @@ -87,14 +84,7 @@ public void append(PythonWriter pythonWriter, OperationSection section) { fileWriter.write("=================\nInput:\n=================\n\n"); fileWriter.write(".. autoclass:: " + inputSymbolName + "\n :members:\n"); fileWriter.write("=================\nOutput:\n=================\n\n"); - if (section.isStream()) { - var streamShape = - context.model().expectShape(output.getAllMembers().get("stream").getId()); - var streamName = context.symbolProvider().toSymbol(streamShape).toString(); - fileWriter.write(".. autodata:: " + streamName + " \n\n"); - } else { - fileWriter.write(".. autoclass:: " + outputSymbolName + "\n " + ":members:\n\n"); - } + fileWriter.write(".. autoclass:: " + outputSymbolName + "\n :members:\n"); }); } } @@ -119,15 +109,7 @@ public void append(PythonWriter pythonWriter, StructureSection section) { var symbol = context.symbolProvider().toSymbol(shape); String docsFileName = String.format("docs/models/%s.rst", symbol.getName()); - - boolean isStreaming = Optional.ofNullable(shape.getAllMembers().get("body")) - .map(member -> context.model().expectShape(member.getTarget())) - .map(memberShape -> memberShape.hasTrait(StreamingTrait.class)) - .orElse(false); - // Input and output shapes are typically skipped since they are generated - // on the operation's page. The exception to this is the output of - // streaming operations where we have a different output shape defined. - if (!shape.hasTrait(InputTrait.class) && !shape.hasTrait(OutputTrait.class) || isStreaming) { + if (!shape.hasTrait(InputTrait.class) && !shape.hasTrait(OutputTrait.class)) { context.writerDelegator().useFileWriter(docsFileName, "", writer -> { writer.write(generateHeader(symbol.getName())); writer.write(".. autoclass:: " + symbol.toString() + "\n :members:\n"); diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java index daca99e19..8e8b4fb49 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java @@ -830,7 +830,7 @@ private void generateOperation(PythonWriter writer, OperationShape operation) { var output = model.expectShape(operation.getOutputShape()); var outputSymbol = symbolProvider.toSymbol(output); - writer.pushState(new OperationSection(service, operation, false)); + writer.pushState(new OperationSection(service, operation)); writer.openBlock("async def $L(self, input: $T, plugins: list[$T] | None = None) -> $T:", "", operationMethodSymbol.getName(), @@ -905,7 +905,7 @@ private void writeSharedOperationInit(PythonWriter writer, OperationShape operat } private void generateEventStreamOperation(PythonWriter writer, OperationShape operation) { - writer.pushState(new OperationSection(service, operation, true)); + writer.pushState(new OperationSection(service, operation)); writer.addDependency(SmithyPythonDependency.SMITHY_CORE); var operationSymbol = symbolProvider.toSymbol(operation); writer.putContext("operation", operationSymbol); diff --git a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/sections/OperationSection.java b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/sections/OperationSection.java index 05a731d7e..ceab19545 100644 --- a/codegen/core/src/main/java/software/amazon/smithy/python/codegen/sections/OperationSection.java +++ b/codegen/core/src/main/java/software/amazon/smithy/python/codegen/sections/OperationSection.java @@ -13,5 +13,4 @@ * A section that controls writing an operation. */ @SmithyInternalApi -public record OperationSection(Shape service, OperationShape operation, - boolean isStream) implements CodeSection {} +public record OperationSection(Shape service, OperationShape operation) implements CodeSection {}