Skip to content

Commit

Permalink
Introduce an aws-lambda feature. (#2035)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
LukeMathWalker committed Nov 29, 2022
1 parent 0adad6a commit 3a9a42b
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 7 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -487,3 +487,15 @@ message = "Make generated enum `values()` functions callable in const contexts."
references = ["smithy-rs#2011"]
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "all" }
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"
Original file line number Diff line number Diff line change
Expand Up @@ -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.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.docs
import software.amazon.smithy.rust.codegen.core.rustlang.rust
Expand Down Expand Up @@ -103,6 +104,21 @@ class PubUsePythonTypesDecorator : RustCodegenDecorator<ServerProtocolGenerator,
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(
/**
* Add the [InternalServerError] error to all operations.
Expand All @@ -115,4 +131,6 @@ val DECORATORS = listOf(
PubUsePythonTypesDecorator(),
// Render the Python shared library export.
PythonExportModuleDecorator(),
// Add the `aws-lambda` feature flag
PythonFeatureFlagsDecorator(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ class PythonApplicationGenerator(
self.run_server(py, address, port, backlog, workers)
}
/// Lambda entrypoint: start the server on Lambda.
##[cfg(feature = "aws-lambda")]
##[pyo3(text_signature = "(${'$'}self)")]
pub fn run_lambda(
&mut self,
Expand Down
5 changes: 4 additions & 1 deletion rust-runtime/aws-smithy-http-server-python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ Python server runtime for Smithy Rust Server Framework.
"""
publish = true

[features]
aws-lambda = ["aws-smithy-http-server/aws-lambda", "dep:lambda_http"]

[dependencies]
aws-smithy-http = { path = "../aws-smithy-http" }
aws-smithy-http-server = { path = "../aws-smithy-http-server" }
Expand All @@ -22,7 +25,7 @@ bytes = "1.2"
futures = "0.3"
http = "0.2"
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"
parking_lot = "0.12.1"
pin-project-lite = "0.2"
Expand Down
2 changes: 2 additions & 0 deletions rust-runtime/aws-smithy-http-server-python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

#![cfg_attr(docsrs, feature(doc_cfg))]

//! Rust/Python bindings, runtime and utilities.
//!
//! This crates implements all the generic code needed to start and manage
Expand Down
6 changes: 5 additions & 1 deletion rust-runtime/aws-smithy-http-server-python/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{collections::HashMap, convert::Infallible, ops::Deref, process, thread

use aws_smithy_http_server::{
body::{Body, BoxBody},
routing::{IntoMakeService, LambdaHandler},
routing::IntoMakeService,
AddExtensionLayer,
};
use http::{Request, Response};
Expand Down Expand Up @@ -422,7 +422,11 @@ event_loop.add_signal_handler(signal.SIGINT,
///
/// Unlike the `run_server`, `run_lambda_handler` does not spawns other processes,
/// 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<()> {
use aws_smithy_http_server::routing::LambdaHandler;

let event_loop = self.configure_python_event_loop(py)?;
let service = self.build_and_configure_service(py, event_loop)?;
let rt = runtime::Builder::new_multi_thread()
Expand Down
3 changes: 2 additions & 1 deletion rust-runtime/aws-smithy-http-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Server runtime for Smithy Rust Server Framework.
publish = true

[features]
aws-lambda = ["dep:lambda_http"]
unredacted-logging = []

[dependencies]
Expand All @@ -26,7 +27,7 @@ futures-util = { version = "0.3", default-features = false }
http = "0.2"
http-body = "0.4"
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"
nom = "7"
pin-project-lite = "0.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ futures-util = "0.3"
lambda_http = "0.7.1"

# Local paths
aws-smithy-http-server = { path = "../../" }
aws-smithy-http-server = { path = "../../", features = ["aws-lambda"] }
pokemon-service-server-sdk = { path = "../pokemon-service-server-sdk/" }

[dev-dependencies]
Expand Down
3 changes: 2 additions & 1 deletion rust-runtime/aws-smithy-http-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
* SPDX-License-Identifier: Apache-2.0
*/

#![cfg_attr(docsrs, feature(doc_cfg))]

//! HTTP server runtime and utilities, loosely based on [axum].
//!
//! [axum]: https://docs.rs/axum/latest/axum/

#[macro_use]
pub(crate) mod macros;

Expand Down
5 changes: 3 additions & 2 deletions rust-runtime/aws-smithy-http-server/src/rejection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,9 @@ convert_to_request_rejection!(std::str::Utf8Error, InvalidUtf8);
// everyone will run a Hyper-based server in their services).
convert_to_request_rejection!(hyper::Error, HttpBody);

// Required in order to accept Lambda HTTP requests using `Router<lambda_http::Body>`.
convert_to_request_rejection!(lambda_http::Error, HttpBody);
// Useful in general, but it also required in order to accept Lambda HTTP requests using
// `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 {
//! This module hosts enums, up to size 8, which implement [`IntoResponse`] when their variants implement
Expand Down
4 changes: 4 additions & 0 deletions rust-runtime/aws-smithy-http-server/src/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ use tower_http::map_response_body::MapResponseBodyLayer;

mod future;
mod into_make_service;
#[cfg(feature = "aws-lambda")]
#[cfg_attr(docsrs, doc(cfg(feature = "aws-lambda")))]
mod lambda_handler;

#[doc(hidden)]
Expand All @@ -38,6 +40,8 @@ mod route;

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::{future::RouterFuture, into_make_service::IntoMakeService, route::Route};

Expand Down

0 comments on commit 3a9a42b

Please sign in to comment.