-
Notifications
You must be signed in to change notification settings - Fork 31
Add experimental Python codegen CLI scaffold #744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| # Code Generator CLI | ||
|
|
||
| The `smithy-python` command is the process interface described in the | ||
| [Python Code Generation](index.md) overview. It supports direct use and | ||
| invocation from Smithy's | ||
| [`run` plugin](https://smithy.io/2.0/guides/smithy-build-json.html#run-plugin). | ||
|
|
||
| ## Commands | ||
|
|
||
| Generation is organized by artifact type: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But what if you could mix artifacts. You don't now - but you could. Types+client or types+server is an obvious combo that's easy to do without much difficulty. smithy-python generate --modes client,typesYou could default that to just be client since most will want that. |
||
|
|
||
| ```console | ||
| smithy-python generate client [OPTIONS] | ||
| smithy-python generate types [OPTIONS] | ||
| ``` | ||
|
|
||
| `client` generates a service client and its required types. `types` generates a | ||
| standalone types package. Both commands accept the following process options: | ||
|
|
||
| * `--model PATH` reads a JSON AST from a file instead of standard input. | ||
| * `--output PATH` selects the output directory for direct invocation. | ||
|
|
||
| Settings specific to each artifact will be added with the functionality that | ||
| consumes them. | ||
|
|
||
| The command MUST return zero after successful generation and non-zero when | ||
| arguments, settings, the model, or generation are invalid. Diagnostics are | ||
| written to standard error. Invalid command syntax and invocation inputs return | ||
| 2, while I/O and generation failures return 1. | ||
|
|
||
| ## Smithy `run` Plugin | ||
|
|
||
| The Smithy `run` plugin executes an external program during a build. It sends the | ||
| projection's Smithy model as a JSON AST to the process's standard input and runs | ||
| the process in the plugin's output directory. | ||
|
|
||
| A plugin ID MUST use `run::` followed by a custom artifact name. The configured | ||
| command identifies the artifact to generate: | ||
|
|
||
| ```json | ||
| { | ||
| "version": "1.0", | ||
| "projections": { | ||
| "client": { | ||
| "plugins": { | ||
| "run::python-client": { | ||
| "command": ["smithy-python", "generate", "client"] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Artifact-specific options will be appended to `command` after they are defined. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is more for my own understanding: the existing Java generator receives {
"run::python-client": {
"command": [
"smithy-python",
"generate",
"client",
"--service",
"com.amazonaws.bedrockruntime#AmazonBedrockFrontendService",
"--module",
"aws_sdk_bedrock_runtime",
"--module-version",
"0.8.0"
]
}
}
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup. I need to look into Jordon's comment to see if We may also grow this overtime to add new options like |
||
|
|
||
| The `smithy-python` executable MUST be installed or otherwise available on the | ||
| Smithy process's `PATH`. Smithy passes no arguments other than those in | ||
| `command`. | ||
|
|
||
| ### Input and Output | ||
|
|
||
| When invoked by Smithy, the CLI reads one JSON AST document from standard input. | ||
| The document represents the model after projection transforms have been applied. | ||
|
|
||
| The presence of `SMITHY_PLUGIN_DIR` identifies an invocation by the `run` plugin. | ||
| Generated files are written beneath this directory, which Smithy also uses as the | ||
| process's working directory. The CLI MUST NOT write generated files outside it, | ||
| and `--model` and `--output` MUST NOT be used in this mode. | ||
|
|
||
| The `run` plugin provides the following environment variables: | ||
|
|
||
| | Name | Purpose | | ||
| |------|---------| | ||
| | `SMITHY_ROOT_DIR` | Root directory of the Smithy build. | | ||
| | `SMITHY_PLUGIN_DIR` | Output and working directory for the plugin. | | ||
| | `SMITHY_PROJECTION_NAME` | Name of the active projection. | | ||
| | `SMITHY_ARTIFACT_NAME` | Custom artifact name from the plugin ID. | | ||
| | `SMITHY_INCLUDES_PRELUDE` | Whether the JSON AST includes prelude shapes. | | ||
|
|
||
| The CLI uses this context to interpret the model. Protocol and platform | ||
| integrations MAY also use it while generating files. | ||
|
|
||
| Smithy omits prelude shapes by default. A build MAY set `sendPrelude` to `true` | ||
| in the `run` plugin configuration when those shapes are needed. | ||
|
|
||
| ## Direct Invocation | ||
|
|
||
| When `SMITHY_PLUGIN_DIR` is absent, the CLI treats the command as a direct | ||
| invocation and requires `--output`. It follows the same | ||
| generation path as Smithy invocation and can read a JSON AST from a file instead | ||
| of standard input by using `--model`. When standard input is an interactive | ||
| terminal, `--model` is required so that an omitted input does not wait indefinitely | ||
| for input. This mode is intended for development, testing, and integration with | ||
| tools other than the Smithy CLI. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # Python Code Generation | ||
|
|
||
| Smithy Python currently generates clients with the Java implementation in | ||
| `codegen`. This document describes the Python code generator that will replace | ||
| that implementation over time. | ||
|
|
||
| The Python generator is distributed as `smithy-python`. It is separate from the | ||
| runtime packages used by generated code, and is only needed while generating a | ||
| package. | ||
|
|
||
| ## Goals | ||
|
|
||
| * Generate Python clients and standalone types packages from Smithy models. | ||
| * Integrate with standard Smithy builds without requiring a Java code generator. | ||
| * Provide extension points for protocol and platform-specific behavior. | ||
| * Produce code compatible with the existing Smithy Python runtime packages. | ||
| * Allow the Python and Java generators to coexist during migration. | ||
|
|
||
| ## Architecture | ||
|
|
||
| The generator consumes a Smithy JSON AST and settings for an artifact. It loads | ||
| the model, applies artifact and protocol-specific behavior, and writes a Python | ||
| package. | ||
|
|
||
| ```text | ||
| Smithy JSON AST + settings | ||
| | | ||
| v | ||
| smithy-python generator | ||
| | | ||
| v | ||
| client or types package | ||
| ``` | ||
|
|
||
| Two artifact types are initially planned: | ||
|
|
||
| * `client` will generate a service client and its required types. | ||
| * `types` will generate a standalone package of types selected from a model. | ||
|
|
||
| The command-line interface is the generator's first entry point. Smithy's `run` | ||
| plugin invokes it as an external process, so the generator does not need to be | ||
| loaded into the Smithy CLI or implemented in Java. | ||
|
|
||
| Generated packages MUST NOT depend on `smithy-python` at runtime. They MAY | ||
| depend on the handwritten runtime packages in this repository. | ||
|
|
||
| ## Migration | ||
|
|
||
| The Java generator remains authoritative while the Python generator is under | ||
| development. Features may be implemented and reviewed incrementally without | ||
| changing the Java path. A generated artifact SHOULD move to the Python generator | ||
| only after the required behavior is supported and tested. | ||
|
|
||
| The Python generator does not need to reproduce Java implementation details or | ||
| byte-for-byte output. It MUST preserve the supported Smithy semantics and public | ||
| behavior of generated packages. | ||
|
|
||
| ## Designs | ||
|
|
||
| * [Code Generator CLI](cli.md) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "type": "feature", | ||
| "description": "Added the experimental smithy-python package and CLI scaffold." | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # Changelog | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note for reviewers: Our release infra will automatically handle version bumping and changelog management. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # smithy-python | ||
|
|
||
| > [!WARNING] | ||
| > This package is an experimental scaffold. It does not generate code yet. The | ||
| > Java generator in the repository's `codegen` directory remains authoritative. | ||
|
|
||
| `smithy-python` will provide Python-native code generation for Smithy models. | ||
| The initial command-line interface exposes the planned client and types generation | ||
| commands so that their top-level shape can be developed independently from the | ||
| generator implementation. | ||
|
|
||
| ```console | ||
| smithy-python generate client [OPTIONS] | ||
| smithy-python generate types [OPTIONS] | ||
| ``` | ||
|
|
||
| After validating their invocation options, both generation commands currently exit | ||
| with an error explaining that generation has not been implemented. The package is | ||
| included in workspace builds to validate its packaging and entry points. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| [project] | ||
| name = "smithy-python" | ||
| dynamic = ["version"] | ||
| requires-python = ">=3.12" | ||
| authors = [ | ||
| {name = "Amazon Web Services"}, | ||
| ] | ||
| description = "A Smithy code generator for Python clients and types." | ||
| readme = "README.md" | ||
| license = {text = "Apache License 2.0"} | ||
| keywords = ["smithy", "codegen", "sdk"] | ||
| classifiers = [ | ||
| "Development Status :: 2 - Pre-Alpha", | ||
| "Intended Audience :: Developers", | ||
| "Natural Language :: English", | ||
| "License :: OSI Approved :: Apache Software License", | ||
| "Operating System :: OS Independent", | ||
| "Programming Language :: Python", | ||
| "Programming Language :: Python :: 3 :: Only", | ||
| "Programming Language :: Python :: 3", | ||
| "Programming Language :: Python :: 3.12", | ||
| "Programming Language :: Python :: 3.13", | ||
| "Programming Language :: Python :: 3.14", | ||
| "Programming Language :: Python :: Implementation :: CPython", | ||
| "Programming Language :: Python :: Free Threading :: 2 - Beta", | ||
| "Topic :: Software Development :: Code Generators", | ||
| ] | ||
| dependencies = [] | ||
|
|
||
| [project.scripts] | ||
| smithy-python = "smithy_python.cli:main" | ||
|
|
||
| [project.urls] | ||
| "Changelog" = "https://github.com/smithy-lang/smithy-python/blob/develop/packages/smithy-python/CHANGELOG.md" | ||
| "Code" = "https://github.com/smithy-lang/smithy-python/tree/develop/packages/smithy-python/" | ||
| "Issue tracker" = "https://github.com/smithy-lang/smithy-python/issues" | ||
|
|
||
| [build-system] | ||
| requires = ["hatchling"] | ||
| build-backend = "hatchling.build" | ||
|
|
||
| [tool.hatch.version] | ||
| path = "src/smithy_python/__init__.py" | ||
|
|
||
| [tool.hatch.build] | ||
| exclude = [ | ||
| "tests", | ||
| ] | ||
|
|
||
| [tool.ruff] | ||
| src = ["src"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| """A Smithy code generator for Python clients and types.""" | ||
|
|
||
| __version__ = "0.0.0" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| from .cli import main | ||
|
|
||
| if __name__ == "__main__": | ||
| raise SystemExit(main()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't talked much about this publicly since I'm still working on implementations and a blog post, but check a look at shape closures. This is a way to drive generation that doesn't root everything in a service.
What it means for you is relatively little, other than that you should tolerate generating without a set service. Current type codegen generates a synthetic one, but you shouldn't operate that way.
Computing a closure is beyond your scope as a non-java plugin. I would suggest rather that you generate what's given to you and put the onus on customers to use smithy-build transforms to narrow it down to what they want. Maybe later you could implement everything needed to compute it and relax that restriction.