mirror of https://github.com/smithy-lang/smithy-rs
Introduce an `aws-lambda` feature. (#2035)
* Introduce an `aws-lambda` feature. * Add CHANGELOG * Use the new and shiny feature syntax to avoid creating an implicit `lambda_http` feature. * Add `aws-lambda` feature to the Python server. Enable the `aws-lambda` feature in our example. Be explicit in providing an implementation of request rejection for Box<dyn Error>. * Add an `aws-lambda` feature flag to the generated Python-specific crate. We enable it by default to make sure the Lambda method ends up visible in the final Python wrapper library.
This commit is contained in:
parent
0adad6a72d
commit
3a9a42bb16
|
@ -487,3 +487,15 @@ message = "Make generated enum `values()` functions callable in const contexts."
|
||||||
references = ["smithy-rs#2011"]
|
references = ["smithy-rs#2011"]
|
||||||
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "all" }
|
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "all" }
|
||||||
author = "lsr0"
|
author = "lsr0"
|
||||||
|
|
||||||
|
[[smithy-rs]]
|
||||||
|
message = """
|
||||||
|
All types that are exclusively relevant within the context of an AWS Lambda function are now gated behind the
|
||||||
|
`aws-lambda` feature flag.
|
||||||
|
|
||||||
|
This will reduce the number of dependencies (and improve build times) for users that are running their Smithy services
|
||||||
|
in non-serverless environments (e.g. via `hyper`).
|
||||||
|
"""
|
||||||
|
references = ["smithy-rs#2035"]
|
||||||
|
meta = { "breaking" = true, "tada" = false, "bug" = false, "target" = "server" }
|
||||||
|
author = "LukeMathWalker"
|
||||||
|
|
|
@ -7,6 +7,7 @@ package software.amazon.smithy.rust.codegen.server.python.smithy.customizations
|
||||||
|
|
||||||
import software.amazon.smithy.model.neighbor.Walker
|
import software.amazon.smithy.model.neighbor.Walker
|
||||||
import software.amazon.smithy.rust.codegen.client.smithy.customize.RustCodegenDecorator
|
import software.amazon.smithy.rust.codegen.client.smithy.customize.RustCodegenDecorator
|
||||||
|
import software.amazon.smithy.rust.codegen.core.rustlang.Feature
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.docs
|
import software.amazon.smithy.rust.codegen.core.rustlang.docs
|
||||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||||
|
@ -103,6 +104,21 @@ class PubUsePythonTypesDecorator : RustCodegenDecorator<ServerProtocolGenerator,
|
||||||
clazz.isAssignableFrom(ServerCodegenContext::class.java)
|
clazz.isAssignableFrom(ServerCodegenContext::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorator adding an `aws-lambda` feature to the generated crate.
|
||||||
|
*/
|
||||||
|
class PythonFeatureFlagsDecorator : RustCodegenDecorator<ServerProtocolGenerator, ServerCodegenContext> {
|
||||||
|
override val name: String = "PythonFeatureFlagsDecorator"
|
||||||
|
override val order: Byte = 0
|
||||||
|
|
||||||
|
override fun extras(codegenContext: ServerCodegenContext, rustCrate: RustCrate) {
|
||||||
|
rustCrate.mergeFeature(Feature("aws-lambda", true, listOf("aws-smithy-http-server-python/aws-lambda")))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun supportsCodegenContext(clazz: Class<out CodegenContext>): Boolean =
|
||||||
|
clazz.isAssignableFrom(ServerCodegenContext::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
val DECORATORS = listOf(
|
val DECORATORS = listOf(
|
||||||
/**
|
/**
|
||||||
* Add the [InternalServerError] error to all operations.
|
* Add the [InternalServerError] error to all operations.
|
||||||
|
@ -115,4 +131,6 @@ val DECORATORS = listOf(
|
||||||
PubUsePythonTypesDecorator(),
|
PubUsePythonTypesDecorator(),
|
||||||
// Render the Python shared library export.
|
// Render the Python shared library export.
|
||||||
PythonExportModuleDecorator(),
|
PythonExportModuleDecorator(),
|
||||||
|
// Add the `aws-lambda` feature flag
|
||||||
|
PythonFeatureFlagsDecorator(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -278,6 +278,7 @@ class PythonApplicationGenerator(
|
||||||
self.run_server(py, address, port, backlog, workers)
|
self.run_server(py, address, port, backlog, workers)
|
||||||
}
|
}
|
||||||
/// Lambda entrypoint: start the server on Lambda.
|
/// Lambda entrypoint: start the server on Lambda.
|
||||||
|
##[cfg(feature = "aws-lambda")]
|
||||||
##[pyo3(text_signature = "(${'$'}self)")]
|
##[pyo3(text_signature = "(${'$'}self)")]
|
||||||
pub fn run_lambda(
|
pub fn run_lambda(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -12,6 +12,9 @@ Python server runtime for Smithy Rust Server Framework.
|
||||||
"""
|
"""
|
||||||
publish = true
|
publish = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
aws-lambda = ["aws-smithy-http-server/aws-lambda", "dep:lambda_http"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aws-smithy-http = { path = "../aws-smithy-http" }
|
aws-smithy-http = { path = "../aws-smithy-http" }
|
||||||
aws-smithy-http-server = { path = "../aws-smithy-http-server" }
|
aws-smithy-http-server = { path = "../aws-smithy-http-server" }
|
||||||
|
@ -22,7 +25,7 @@ bytes = "1.2"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
http = "0.2"
|
http = "0.2"
|
||||||
hyper = { version = "0.14.20", features = ["server", "http1", "http2", "tcp", "stream"] }
|
hyper = { version = "0.14.20", features = ["server", "http1", "http2", "tcp", "stream"] }
|
||||||
lambda_http = "0.7.1"
|
lambda_http = { version = "0.7.1", optional = true }
|
||||||
num_cpus = "1.13.1"
|
num_cpus = "1.13.1"
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
pin-project-lite = "0.2"
|
pin-project-lite = "0.2"
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
|
|
||||||
//! Rust/Python bindings, runtime and utilities.
|
//! Rust/Python bindings, runtime and utilities.
|
||||||
//!
|
//!
|
||||||
//! This crates implements all the generic code needed to start and manage
|
//! This crates implements all the generic code needed to start and manage
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::{collections::HashMap, convert::Infallible, ops::Deref, process, thread
|
||||||
|
|
||||||
use aws_smithy_http_server::{
|
use aws_smithy_http_server::{
|
||||||
body::{Body, BoxBody},
|
body::{Body, BoxBody},
|
||||||
routing::{IntoMakeService, LambdaHandler},
|
routing::IntoMakeService,
|
||||||
AddExtensionLayer,
|
AddExtensionLayer,
|
||||||
};
|
};
|
||||||
use http::{Request, Response};
|
use http::{Request, Response};
|
||||||
|
@ -422,7 +422,11 @@ event_loop.add_signal_handler(signal.SIGINT,
|
||||||
///
|
///
|
||||||
/// Unlike the `run_server`, `run_lambda_handler` does not spawns other processes,
|
/// Unlike the `run_server`, `run_lambda_handler` does not spawns other processes,
|
||||||
/// it starts the Lambda handler on the current process.
|
/// it starts the Lambda handler on the current process.
|
||||||
|
#[cfg(feature = "aws-lambda")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "aws-lambda")))]
|
||||||
fn run_lambda_handler(&mut self, py: Python) -> PyResult<()> {
|
fn run_lambda_handler(&mut self, py: Python) -> PyResult<()> {
|
||||||
|
use aws_smithy_http_server::routing::LambdaHandler;
|
||||||
|
|
||||||
let event_loop = self.configure_python_event_loop(py)?;
|
let event_loop = self.configure_python_event_loop(py)?;
|
||||||
let service = self.build_and_configure_service(py, event_loop)?;
|
let service = self.build_and_configure_service(py, event_loop)?;
|
||||||
let rt = runtime::Builder::new_multi_thread()
|
let rt = runtime::Builder::new_multi_thread()
|
||||||
|
|
|
@ -13,6 +13,7 @@ Server runtime for Smithy Rust Server Framework.
|
||||||
publish = true
|
publish = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
aws-lambda = ["dep:lambda_http"]
|
||||||
unredacted-logging = []
|
unredacted-logging = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -26,7 +27,7 @@ futures-util = { version = "0.3", default-features = false }
|
||||||
http = "0.2"
|
http = "0.2"
|
||||||
http-body = "0.4"
|
http-body = "0.4"
|
||||||
hyper = { version = "0.14.12", features = ["server", "http1", "http2", "tcp", "stream"] }
|
hyper = { version = "0.14.12", features = ["server", "http1", "http2", "tcp", "stream"] }
|
||||||
lambda_http = "0.7.1"
|
lambda_http = { version = "0.7.1", optional = true }
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
nom = "7"
|
nom = "7"
|
||||||
pin-project-lite = "0.2"
|
pin-project-lite = "0.2"
|
||||||
|
|
|
@ -44,7 +44,7 @@ futures-util = "0.3"
|
||||||
lambda_http = "0.7.1"
|
lambda_http = "0.7.1"
|
||||||
|
|
||||||
# Local paths
|
# Local paths
|
||||||
aws-smithy-http-server = { path = "../../" }
|
aws-smithy-http-server = { path = "../../", features = ["aws-lambda"] }
|
||||||
pokemon-service-server-sdk = { path = "../pokemon-service-server-sdk/" }
|
pokemon-service-server-sdk = { path = "../pokemon-service-server-sdk/" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
|
|
||||||
//! HTTP server runtime and utilities, loosely based on [axum].
|
//! HTTP server runtime and utilities, loosely based on [axum].
|
||||||
//!
|
//!
|
||||||
//! [axum]: https://docs.rs/axum/latest/axum/
|
//! [axum]: https://docs.rs/axum/latest/axum/
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub(crate) mod macros;
|
pub(crate) mod macros;
|
||||||
|
|
||||||
|
|
|
@ -261,8 +261,9 @@ convert_to_request_rejection!(std::str::Utf8Error, InvalidUtf8);
|
||||||
// everyone will run a Hyper-based server in their services).
|
// everyone will run a Hyper-based server in their services).
|
||||||
convert_to_request_rejection!(hyper::Error, HttpBody);
|
convert_to_request_rejection!(hyper::Error, HttpBody);
|
||||||
|
|
||||||
// Required in order to accept Lambda HTTP requests using `Router<lambda_http::Body>`.
|
// Useful in general, but it also required in order to accept Lambda HTTP requests using
|
||||||
convert_to_request_rejection!(lambda_http::Error, HttpBody);
|
// `Router<lambda_http::Body>` since `lambda_http::Error` is a type alias for `Box<dyn Error + ..>`.
|
||||||
|
convert_to_request_rejection!(Box<dyn std::error::Error + Send + Sync + 'static>, HttpBody);
|
||||||
|
|
||||||
pub mod any_rejections {
|
pub mod any_rejections {
|
||||||
//! This module hosts enums, up to size 8, which implement [`IntoResponse`] when their variants implement
|
//! This module hosts enums, up to size 8, which implement [`IntoResponse`] when their variants implement
|
||||||
|
|
|
@ -29,6 +29,8 @@ use tower_http::map_response_body::MapResponseBodyLayer;
|
||||||
|
|
||||||
mod future;
|
mod future;
|
||||||
mod into_make_service;
|
mod into_make_service;
|
||||||
|
#[cfg(feature = "aws-lambda")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "aws-lambda")))]
|
||||||
mod lambda_handler;
|
mod lambda_handler;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -38,6 +40,8 @@ mod route;
|
||||||
|
|
||||||
pub(crate) mod tiny_map;
|
pub(crate) mod tiny_map;
|
||||||
|
|
||||||
|
#[cfg(feature = "aws-lambda")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "aws-lambda")))]
|
||||||
pub use self::lambda_handler::LambdaHandler;
|
pub use self::lambda_handler::LambdaHandler;
|
||||||
pub use self::{future::RouterFuture, into_make_service::IntoMakeService, route::Route};
|
pub use self::{future::RouterFuture, into_make_service::IntoMakeService, route::Route};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue