Skip to content

Commit

Permalink
Enable shapes-only codegen
Browse files Browse the repository at this point in the history
This adds an alternative generation mode that only generates "data
shapes".
  • Loading branch information
JordonPhillips committed Feb 25, 2025
1 parent 1a83ad2 commit 56c766e
Show file tree
Hide file tree
Showing 23 changed files with 1,746 additions and 174 deletions.
153 changes: 150 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This repository does *not* contain any generated clients, such as for S3 or othe
AWS services. Rather, these are the tools that facilitate the generation of those
clients and non-AWS Smithy clients.

### How do I use this?
### How do I use this to create a client?

The first step is to create a Smithy package. If this is your first time working
with Smithy, follow [this quickstart guide](https://smithy.io/2.0/quickstart.html)
Expand Down Expand Up @@ -82,8 +82,8 @@ this file, see the
"sources": ["model"],
"maven": {
"dependencies": [
"software.amazon.smithy:smithy-model:[1.34.0,2.0)",
"software.amazon.smithy:smithy-aws-traits:[1.34.0,2.0)",
"software.amazon.smithy:smithy-model:[1.54.0,2.0)",
"software.amazon.smithy:smithy-aws-traits:[1.54.0,2.0)",
"software.amazon.smithy.python:smithy-python-codegen:0.1.0"
]
},
Expand Down Expand Up @@ -175,6 +175,153 @@ Only for now. Once the generator has been published, the Smithy CLI will be able
to run it without a separate Java installation. Similarly, once the python
helper libraries have been published you won't need to install them locally.

### How do I generate types for shapes without a client?

If all you want are concrete Python classes for the shapes in your Smithy model,
all you need to do is replace `python-client-codegen` with
`python-type-codegen` when following the steps above. Your `smithy-build.json`
would now look like:

```json
{
"version": "1.0",
"sources": ["model"],
"maven": {
"dependencies": [
"software.amazon.smithy:smithy-model:[1.54.0,2.0)",
"software.amazon.smithy.python:smithy-python-codegen:0.1.0"
]
},
"projections": {
"shapes": {
"plugins": {
"python-type-codegen": {
"service": "com.example#EchoService",
"module": "echo",
"moduleVersion": "0.0.1"
}
}
}
}
}
```

The module with the generated shape classes can be found in
`build/smithy/client/python-type-codegen` after you run `smithy-build`.

Unlike when generating a client, a service shape is not required for shape
generation. If a service is not provided then every shape found in the model
will be generated. Any naming conflicts may be resolved by using the
[`renameShapes` transform](https://smithy.io/2.0/guides/smithy-build-json.html#renameshapes)
(or renaming the shapes in the model of course).

The set of shapes generated can also be constrained by using the
[`includeShapesBySelector` transform](https://smithy.io/2.0/guides/smithy-build-json.html#includeshapesbyselector).
For example, to generate only shapes within the `com.example` namespace:

```json
{
"version": "1.0",
"sources": ["model"],
"maven": {
"dependencies": [
"software.amazon.smithy:smithy-model:[1.54.0,2.0)",
"software.amazon.smithy.python:smithy-python-codegen:0.1.0"
]
},
"projections": {
"shapes": {
"transforms": [
{
"name": "includeShapesBySelector",
"args": {
"selector": "[id|namespace = 'com.example']"
}
}
],
"plugins": {
"python-type-codegen": {
"module": "echo",
"moduleVersion": "0.0.1"
}
}
}
}
}
```

Input and output shapes (shapes with the `@input` or `@output` traits and
operation inputs / outputs created as part of an operation definition) are not
generated by default. To generate these shapes anyway, remove the traits with
the
[`excludeTraits` transform](https://smithy.io/2.0/guides/smithy-build-json.html#excludetraits):

```json
{
"version": "1.0",
"sources": ["model"],
"maven": {
"dependencies": [
"software.amazon.smithy:smithy-model:[1.54.0,2.0)",
"software.amazon.smithy.python:smithy-python-codegen:0.1.0"
]
},
"projections": {
"shapes": {
"transforms": [
{
"name": "excludeTraits",
"args": {
"traits": ["input", "output"]
}
}
],
"plugins": {
"python-type-codegen": {
"module": "echo",
"moduleVersion": "0.0.1"
}
}
}
}
}
```

You can also generate both a client package and a shape package in one build,
but they won't depend on each other. To do this, just add both plugins in the
projection, or create a projection for each plugin. Below is an example showing
both plugins in one projection:

```json
{
"version": "1.0",
"sources": ["model"],
"maven": {
"dependencies": [
"software.amazon.smithy:smithy-model:[1.54.0,2.0)",
"software.amazon.smithy:smithy-aws-traits:[1.54.0,2.0)",
"software.amazon.smithy.python:smithy-python-codegen:0.1.0"
]
},
"projections": {
"client": {
"plugins": {
"python-client-codegen": {
"service": "com.example#EchoService",
"module": "echo",
"moduleVersion": "0.0.1"
},
"python-type-codegen": {
"service": "com.example#EchoService",
"module": "echo",
"moduleVersion": "0.0.1"
}
}
}
}
}
```

### Core Modules and Interfaces

* `smithy-core` provides transport-agnostic core modules and interfaces
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import org.gradle.api.Project

plugins {
id("smithy-python.module-conventions")
id("smithy-python.integ-test-conventions")
}

// Workaround per: https://github.com/gradle/gradle/issues/15383
val Project.libs get() = the<org.gradle.accessors.dm.LibrariesForLibs>()

group = "software.amazon.smithy.python.codegen.plugins"

dependencies {
implementation(libs.smithy.codegen)
implementation(project(":core"))

// Avoid circular dependency in codegen core
if (project.name != "core") {
api(project(":core"))
}
}

val generatedSrcDir = layout.buildDirectory.dir("generated-src").get()

// Add generated sources to integration test sources
sourceSets {
named("it") {
java {
srcDir(generatedSrcDir)
}
}
}

// Ensure integ tests are executed as part of test suite
tasks["test"].finalizedBy("integ")
Loading

0 comments on commit 56c766e

Please sign in to comment.