Skip to content
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

Remove old service builder machinery #2161

Merged
merged 22 commits into from Jan 20, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -10,16 +10,19 @@ import software.amazon.smithy.build.PluginContext
import software.amazon.smithy.codegen.core.CodegenException
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.knowledge.NullableIndex
import software.amazon.smithy.model.shapes.OperationShape
import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.StringShape
import software.amazon.smithy.model.shapes.StructureShape
import software.amazon.smithy.model.shapes.UnionShape
import software.amazon.smithy.model.traits.EnumTrait
import software.amazon.smithy.rust.codegen.core.rustlang.RustModule
import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.core.smithy.CodegenTarget
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
import software.amazon.smithy.rust.codegen.core.smithy.SymbolVisitorConfig
import software.amazon.smithy.rust.codegen.server.python.smithy.generators.PythonServerEnumGenerator
import software.amazon.smithy.rust.codegen.server.python.smithy.generators.PythonServerOperationHandlerGenerator
import software.amazon.smithy.rust.codegen.server.python.smithy.generators.PythonServerServiceGenerator
import software.amazon.smithy.rust.codegen.server.python.smithy.generators.PythonServerStructureGenerator
import software.amazon.smithy.rust.codegen.server.smithy.ServerCodegenContext
Expand Down Expand Up @@ -164,4 +167,11 @@ class PythonServerCodegenVisitor(
)
.render()
}

override fun operationShape(shape: OperationShape) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to live in operation_handler.rs but since we removed this module we opt to generate it via the CodegenVisitor.

super.operationShape(shape)
rustCrate.withModule(RustModule.public("python_operation_adaptor")) {
PythonServerOperationHandlerGenerator(codegenContext, shape).render(this)
}
}
}
Expand Up @@ -199,7 +199,7 @@ class PythonApplicationGenerator(
let ${name}_locals = #{pyo3_asyncio}::TaskLocals::new(event_loop);
let handler = self.handlers.get("$name").expect("Python handler for operation `$name` not found").clone();
let builder = builder.$name(move |input, state| {
#{pyo3_asyncio}::tokio::scope(${name}_locals.clone(), crate::operation_handler::$name(input, state, handler.clone()))
#{pyo3_asyncio}::tokio::scope(${name}_locals.clone(), crate::python_operation_adaptor::$name(input, state, handler.clone()))
});
""",
*codegenScope,
Expand Down
Expand Up @@ -13,8 +13,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.core.util.toSnakeCase
import software.amazon.smithy.rust.codegen.server.python.smithy.PythonServerCargoDependency
import software.amazon.smithy.rust.codegen.server.smithy.generators.ServerOperationHandlerGenerator
import software.amazon.smithy.rust.codegen.server.smithy.generators.protocol.ServerProtocol

/**
* The Rust code responsible to run the Python business logic on the Python interpreter
Expand All @@ -32,9 +30,8 @@ import software.amazon.smithy.rust.codegen.server.smithy.generators.protocol.Ser
*/
class PythonServerOperationHandlerGenerator(
codegenContext: CodegenContext,
protocol: ServerProtocol,
private val operations: List<OperationShape>,
) : ServerOperationHandlerGenerator(codegenContext, protocol, operations) {
private val operation: OperationShape,
) {
private val symbolProvider = codegenContext.symbolProvider
private val runtimeConfig = codegenContext.runtimeConfig
private val codegenScope =
Expand All @@ -47,42 +44,39 @@ class PythonServerOperationHandlerGenerator(
"tracing" to PythonServerCargoDependency.Tracing.toType(),
)

override fun render(writer: RustWriter) {
super.render(writer)
fun render(writer: RustWriter) {
renderPythonOperationHandlerImpl(writer)
}

private fun renderPythonOperationHandlerImpl(writer: RustWriter) {
for (operation in operations) {
val operationName = symbolProvider.toSymbol(operation).name
val input = "crate::input::${operationName}Input"
val output = "crate::output::${operationName}Output"
val error = "crate::error::${operationName}Error"
val fnName = operationName.toSnakeCase()
val operationName = symbolProvider.toSymbol(operation).name
val input = "crate::input::${operationName}Input"
val output = "crate::output::${operationName}Output"
val error = "crate::error::${operationName}Error"
val fnName = operationName.toSnakeCase()

writer.rustTemplate(
"""
/// Python handler for operation `$operationName`.
pub(crate) async fn $fnName(
input: $input,
state: #{SmithyServer}::Extension<#{SmithyPython}::context::PyContext>,
handler: #{SmithyPython}::PyHandler,
) -> std::result::Result<$output, $error> {
// Async block used to run the handler and catch any Python error.
let result = if handler.is_coroutine {
#{PyCoroutine:W}
} else {
#{PyFunction:W}
};
#{PyError:W}
}
""",
*codegenScope,
"PyCoroutine" to renderPyCoroutine(fnName, output),
"PyFunction" to renderPyFunction(fnName, output),
"PyError" to renderPyError(),
)
}
writer.rustTemplate(
"""
/// Python handler for operation `$operationName`.
pub(crate) async fn $fnName(
input: $input,
state: #{SmithyServer}::Extension<#{SmithyPython}::context::PyContext>,
handler: #{SmithyPython}::PyHandler,
) -> std::result::Result<$output, $error> {
// Async block used to run the handler and catch any Python error.
let result = if handler.is_coroutine {
#{PyCoroutine:W}
} else {
#{PyFunction:W}
};
#{PyError:W}
}
""",
*codegenScope,
"PyCoroutine" to renderPyCoroutine(fnName, output),
"PyFunction" to renderPyFunction(fnName, output),
"PyError" to renderPyError(),
)
}

private fun renderPyFunction(name: String, output: String): Writable =
Expand Down
Expand Up @@ -33,10 +33,6 @@ class PythonServerServiceGenerator(
PythonServerOperationErrorGenerator(context.model, context.symbolProvider, operation).render(writer)
}

override fun renderOperationHandler(writer: RustWriter, operations: List<OperationShape>) {
PythonServerOperationHandlerGenerator(context, protocol, operations).render(writer)
}

override fun renderExtras(operations: List<OperationShape>) {
rustCrate.withModule(RustModule.public("python_server_application", "Python server and application implementation.")) {
PythonApplicationGenerator(context, protocol, operations)
Expand Down
Expand Up @@ -7,8 +7,6 @@ package software.amazon.smithy.rust.codegen.server.smithy
import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.core.rustlang.CratesIo
import software.amazon.smithy.rust.codegen.core.rustlang.DependencyScope
import software.amazon.smithy.rust.codegen.core.rustlang.InlineDependency
import software.amazon.smithy.rust.codegen.core.rustlang.RustModule
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig

/**
Expand All @@ -27,32 +25,8 @@ object ServerCargoDependency {
val Tower: CargoDependency = CargoDependency("tower", CratesIo("0.4"))
val TokioDev: CargoDependency = CargoDependency("tokio", CratesIo("1.8.4"), scope = DependencyScope.Dev)
val Regex: CargoDependency = CargoDependency("regex", CratesIo("1.5.5"))
val HyperDev: CargoDependency = CargoDependency("hyper", CratesIo("0.14.12"), DependencyScope.Dev)

fun smithyHttpServer(runtimeConfig: RuntimeConfig) = runtimeConfig.smithyRuntimeCrate("smithy-http-server")
fun smithyTypes(runtimeConfig: RuntimeConfig) = runtimeConfig.smithyRuntimeCrate("smithy-types")
}

/**
* A dependency on a snippet of code
*
* ServerInlineDependency should not be instantiated directly, rather, it should be constructed with
* [software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.forInlineFun]
*
* ServerInlineDependencies are created as private modules within the main crate. This is useful for any code that
* doesn't need to exist in a shared crate, but must still be generated exactly once during codegen.
*
* CodegenVisitor de-duplicates inline dependencies by (module, name) during code generation.
*/
object ServerInlineDependency {
fun serverOperationHandler(runtimeConfig: RuntimeConfig): InlineDependency =
InlineDependency.forRustFile(
RustModule.private("server_operation_handler_trait"),
"/inlineable/src/server_operation_handler_trait.rs",
ServerCargoDependency.smithyHttpServer(runtimeConfig),
CargoDependency.Http,
ServerCargoDependency.PinProjectLite,
ServerCargoDependency.Tower,
ServerCargoDependency.FuturesUtil,
ServerCargoDependency.AsyncTrait,
)
}
Expand Up @@ -19,9 +19,6 @@ object ServerRuntimeType {

fun router(runtimeConfig: RuntimeConfig) = ServerCargoDependency.smithyHttpServer(runtimeConfig).toType().resolve("routing::Router")

fun operationHandler(runtimeConfig: RuntimeConfig) =
forInlineDependency(ServerInlineDependency.serverOperationHandler(runtimeConfig))

fun runtimeError(runtimeConfig: RuntimeConfig) = ServerCargoDependency.smithyHttpServer(runtimeConfig).toType().resolve("runtime_error::RuntimeError")

fun requestRejection(runtimeConfig: RuntimeConfig) = ServerCargoDependency.smithyHttpServer(runtimeConfig).toType().resolve("rejection::RequestRejection")
Expand Down

This file was deleted.