From 2c8f5361f63c0ff1d827fdced13e93a807db0024 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Fri, 7 Oct 2022 14:02:57 +0000 Subject: [PATCH] Update Python implementation Fix python tests Restore default --- .../generators/PythonApplicationGenerator.kt | 41 ++++++---- .../PythonServerOperationHandlerGenerator.kt | 4 +- .../PythonServerServiceGenerator.kt | 4 +- .../ServerOperationHandlerGenerator.kt | 2 +- .../generators/ServerServiceGenerator.kt | 2 +- .../src/error.rs | 77 +++++++++++-------- .../src/middleware/handler.rs | 67 +++++++--------- .../src/middleware/layer.rs | 65 +++++----------- .../src/server.rs | 2 - 9 files changed, 128 insertions(+), 136 deletions(-) diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt index 1f3e3e197a6..242b4a3acd2 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt @@ -23,6 +23,7 @@ import software.amazon.smithy.rust.codegen.core.util.outputShape 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.ServerCargoDependency +import software.amazon.smithy.rust.codegen.server.smithy.generators.protocol.ServerProtocol /** * Generates a Python compatible application and server that can be configured from Python. @@ -62,13 +63,13 @@ import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency */ class PythonApplicationGenerator( codegenContext: CodegenContext, + private val protocol: ServerProtocol, private val operations: List, ) { private val symbolProvider = codegenContext.symbolProvider private val libName = "lib${codegenContext.settings.moduleName.toSnakeCase()}" private val runtimeConfig = codegenContext.runtimeConfig private val model = codegenContext.model - private val protocol = codegenContext.protocol private val codegenScope = arrayOf( "SmithyPython" to PythonServerCargoDependency.SmithyHttpServerPython(runtimeConfig).asType(), @@ -88,6 +89,7 @@ class PythonApplicationGenerator( fun render(writer: RustWriter) { renderPyApplicationRustDocs(writer) renderAppStruct(writer) + renderAppDefault(writer) renderAppClone(writer) renderPyAppTrait(writer) renderAppImpl(writer) @@ -98,7 +100,7 @@ class PythonApplicationGenerator( writer.rustTemplate( """ ##[#{pyo3}::pyclass] - ##[derive(Debug, Default)] + ##[derive(Debug)] pub struct App { handlers: #{HashMap}, middlewares: #{SmithyPython}::PyMiddlewares, @@ -128,6 +130,23 @@ class PythonApplicationGenerator( ) } + private fun renderAppDefault(writer: RustWriter) { + writer.rustTemplate( + """ + impl Default for App { + fn default() -> Self { + Self { + handlers: Default::default(), + middlewares: #{SmithyPython}::PyMiddlewares::new::<#{Protocol}>(vec![]), + context: None, + workers: #{parking_lot}::Mutex::new(vec![]), + } + } + } + """, + ) + } + private fun renderAppImpl(writer: RustWriter) { writer.rustBlockTemplate( """ @@ -165,20 +184,17 @@ class PythonApplicationGenerator( rustTemplate( """ let middleware_locals = pyo3_asyncio::TaskLocals::new(event_loop); - use #{SmithyPython}::PyApp; - let service = #{tower}::ServiceBuilder::new().layer( - #{SmithyPython}::PyMiddlewareLayer::new( - self.middlewares.clone(), - self.protocol(), - middleware_locals - )?, - ); + let service = #{tower}::ServiceBuilder::new() + .layer( + #{SmithyPython}::PyMiddlewareLayer::<#{Protocol}>::new(self.middlewares.clone(), middleware_locals), + ); let router: #{SmithyServer}::routing::Router = router .build() .expect("Unable to build operation registry") .into(); Ok(router.layer(service)) """, + "Protocol" to protocol.markerStruct(), *codegenScope, ) } @@ -186,7 +202,6 @@ class PythonApplicationGenerator( } private fun renderPyAppTrait(writer: RustWriter) { - val protocol = protocol.toString().replace("#", "##") writer.rustTemplate( """ impl #{SmithyPython}::PyApp for App { @@ -202,9 +217,6 @@ class PythonApplicationGenerator( fn middlewares(&mut self) -> &mut #{SmithyPython}::PyMiddlewares { &mut self.middlewares } - fn protocol(&self) -> &'static str { - "$protocol" - } } """, *codegenScope, @@ -264,6 +276,7 @@ class PythonApplicationGenerator( self.start_hyper_worker(py, socket, event_loop, router, worker_number) } """, + "Protocol" to protocol.markerStruct(), *codegenScope, ) operations.map { operation -> diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerOperationHandlerGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerOperationHandlerGenerator.kt index 6f814d7ee3a..076a7570143 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerOperationHandlerGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerOperationHandlerGenerator.kt @@ -16,6 +16,7 @@ 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.ServerCargoDependency 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 @@ -33,8 +34,9 @@ import software.amazon.smithy.rust.codegen.server.smithy.generators.ServerOperat */ class PythonServerOperationHandlerGenerator( codegenContext: CodegenContext, + protocol: ServerProtocol, private val operations: List, -) : ServerOperationHandlerGenerator(codegenContext, operations) { +) : ServerOperationHandlerGenerator(codegenContext, protocol, operations) { private val symbolProvider = codegenContext.symbolProvider private val runtimeConfig = codegenContext.runtimeConfig private val codegenScope = diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerServiceGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerServiceGenerator.kt index ce1bf6a36f0..56e119a87e7 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerServiceGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerServiceGenerator.kt @@ -34,12 +34,12 @@ class PythonServerServiceGenerator( } override fun renderOperationHandler(writer: RustWriter, operations: List) { - PythonServerOperationHandlerGenerator(context, operations).render(writer) + PythonServerOperationHandlerGenerator(context, protocol, operations).render(writer) } override fun renderExtras(operations: List) { rustCrate.withModule(RustModule.public("python_server_application", "Python server and application implementation.")) { writer -> - PythonApplicationGenerator(context, operations) + PythonApplicationGenerator(context, protocol, operations) .render(writer) } } diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerOperationHandlerGenerator.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerOperationHandlerGenerator.kt index ec129e6ef1c..5a3c93b2be9 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerOperationHandlerGenerator.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerOperationHandlerGenerator.kt @@ -29,7 +29,7 @@ import software.amazon.smithy.rust.codegen.server.smithy.protocols.ServerHttpBou */ open class ServerOperationHandlerGenerator( codegenContext: CodegenContext, - private val protocol: ServerProtocol, + val protocol: ServerProtocol, private val operations: List, ) { private val serverCrate = "aws_smithy_http_server" diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerServiceGenerator.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerServiceGenerator.kt index e641f99c0c3..2e659adc263 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerServiceGenerator.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerServiceGenerator.kt @@ -29,7 +29,7 @@ open class ServerServiceGenerator( private val rustCrate: RustCrate, private val protocolGenerator: ServerProtocolGenerator, private val protocolSupport: ProtocolSupport, - private val protocol: ServerProtocol, + val protocol: ServerProtocol, private val codegenContext: CodegenContext, ) { private val index = TopDownIndex.of(codegenContext.model) diff --git a/rust-runtime/aws-smithy-http-server-python/src/error.rs b/rust-runtime/aws-smithy-http-server-python/src/error.rs index 519e75501a6..a6396fa969d 100644 --- a/rust-runtime/aws-smithy-http-server-python/src/error.rs +++ b/rust-runtime/aws-smithy-http-server-python/src/error.rs @@ -5,8 +5,14 @@ //! Python error definition. -use aws_smithy_http_server::protocols::Protocol; -use aws_smithy_http_server::{body::to_boxed, response::Response}; +use aws_smithy_http_server::{ + body::{to_boxed, BoxBody}, + proto::{ + aws_json_10::AwsJson10, aws_json_11::AwsJson11, rest_json_1::AwsRestJson1, + rest_xml::AwsRestXml, + }, + response::IntoResponse, +}; use aws_smithy_types::date_time::{ConversionError, DateTimeParseError}; use pyo3::{create_exception, exceptions::PyException as BasePyException, prelude::*, PyErr}; use thiserror::Error; @@ -62,39 +68,50 @@ impl From for PyMiddlewareException { } } -impl PyMiddlewareException { - /// Convert the exception into a [Response], following the [Protocol] specification. - pub(crate) fn into_response(self, protocol: Protocol) -> Response { - let body = to_boxed(match protocol { - Protocol::RestJson1 => self.json_body(), - Protocol::RestXml => self.xml_body(), - // See https://awslabs.github.io/smithy/1.0/spec/aws/aws-json-1_0-protocol.html#empty-body-serialization - Protocol::AwsJson10 => self.json_body(), - // See https://awslabs.github.io/smithy/1.0/spec/aws/aws-json-1_1-protocol.html#empty-body-serialization - Protocol::AwsJson11 => self.json_body(), - }); +impl IntoResponse for PyMiddlewareException { + fn into_response(self) -> http::Response { + http::Response::builder() + .status(self.status_code) + .header("Content-Type", "application/json") + .header("X-Amzn-Errortype", "MiddlewareException") + .body(to_boxed(self.json_body())) + .expect("invalid HTTP response for `MiddlewareException`; please file a bug report under https://github.com/awslabs/smithy-rs/issues") + } +} - let mut builder = http::Response::builder(); - builder = builder.status(self.status_code); +impl IntoResponse for PyMiddlewareException { + fn into_response(self) -> http::Response { + http::Response::builder() + .status(self.status_code) + .header("Content-Type", "application/xml") + .body(to_boxed(self.xml_body())) + .expect("invalid HTTP response for `MiddlewareException`; please file a bug report under https://github.com/awslabs/smithy-rs/issues") + } +} - match protocol { - Protocol::RestJson1 => { - builder = builder - .header("Content-Type", "application/json") - .header("X-Amzn-Errortype", "MiddlewareException"); - } - Protocol::RestXml => builder = builder.header("Content-Type", "application/xml"), - Protocol::AwsJson10 => { - builder = builder.header("Content-Type", "application/x-amz-json-1.0") - } - Protocol::AwsJson11 => { - builder = builder.header("Content-Type", "application/x-amz-json-1.1") - } - } +impl IntoResponse for PyMiddlewareException { + fn into_response(self) -> http::Response { + http::Response::builder() + .status(self.status_code) + .header("Content-Type", "application/x-amz-json-1.0") + // See https://awslabs.github.io/smithy/1.0/spec/aws/aws-json-1_0-protocol.html#empty-body-serialization + .body(to_boxed(self.json_body())) + .expect("invalid HTTP response for `MiddlewareException`; please file a bug report under https://github.com/awslabs/smithy-rs/issues") + } +} - builder.body(body).expect("invalid HTTP response for `MiddlewareException`; please file a bug report under https://github.com/awslabs/smithy-rs/issues") +impl IntoResponse for PyMiddlewareException { + fn into_response(self) -> http::Response { + http::Response::builder() + .status(self.status_code) + .header("Content-Type", "application/x-amz-json-1.1") + // See https://awslabs.github.io/smithy/1.0/spec/aws/aws-json-1_1-protocol.html#empty-body-serialization + .body(to_boxed(self.json_body())) + .expect("invalid HTTP response for `MiddlewareException`; please file a bug report under https://github.com/awslabs/smithy-rs/issues") } +} +impl PyMiddlewareException { /// Serialize the body into a JSON object. fn json_body(&self) -> String { let mut out = String::new(); diff --git a/rust-runtime/aws-smithy-http-server-python/src/middleware/handler.rs b/rust-runtime/aws-smithy-http-server-python/src/middleware/handler.rs index 00f99312e85..20a4104925e 100644 --- a/rust-runtime/aws-smithy-http-server-python/src/middleware/handler.rs +++ b/rust-runtime/aws-smithy-http-server-python/src/middleware/handler.rs @@ -4,11 +4,10 @@ */ //! Execute Python middleware handlers. -use aws_smithy_http_server::body::Body; +use aws_smithy_http_server::{body::Body, body::BoxBody, response::IntoResponse}; use http::Request; use pyo3::prelude::*; -use aws_smithy_http_server::protocols::Protocol; use pyo3_asyncio::TaskLocals; use crate::{PyMiddlewareException, PyRequest, PyResponse}; @@ -36,18 +35,27 @@ pub struct PyMiddlewareHandler { /// Structure holding the list of Python middlewares that will be executed by this server. /// /// Middlewares are executed one after each other inside the [crate::PyMiddlewareLayer] Tower layer. -#[derive(Debug, Clone, Default)] -pub struct PyMiddlewares(Vec); +#[derive(Debug, Clone)] +pub struct PyMiddlewares { + handlers: Vec, + into_response: fn(PyMiddlewareException) -> http::Response, +} impl PyMiddlewares { /// Create a new instance of `PyMiddlewareHandlers` from a list of heandlers. - pub fn new(handlers: Vec) -> Self { - Self(handlers) + pub fn new

(handlers: Vec) -> Self + where + PyMiddlewareException: IntoResponse

, + { + Self { + handlers, + into_response: PyMiddlewareException::into_response, + } } /// Add a new handler to the list. pub fn push(&mut self, handler: PyMiddlewareHandler) { - self.0.push(handler); + self.handlers.push(handler); } /// Execute a single middleware handler. @@ -114,13 +122,9 @@ impl PyMiddlewares { /// and return a protocol specific error, with the option of setting the HTTP return code. /// * Middleware raising any other exception will immediately terminate the request handling and /// return a protocol specific error, with HTTP status code 500. - pub fn run( - &mut self, - mut request: Request, - protocol: Protocol, - locals: TaskLocals, - ) -> PyFuture { - let handlers = self.0.clone(); + pub fn run(&mut self, mut request: Request, locals: TaskLocals) -> PyFuture { + let handlers = self.handlers.clone(); + let into_response = self.into_response; // Run all Python handlers in a loop. Box::pin(async move { tracing::debug!("Executing Python middleware stack"); @@ -152,7 +156,7 @@ impl PyMiddlewares { tracing::debug!( "Middleware `{name}` returned an error, exit middleware loop" ); - return Err(e.into_response(protocol)); + return Err((into_response)(e)); } } } @@ -166,6 +170,7 @@ impl PyMiddlewares { #[cfg(test)] mod tests { + use aws_smithy_http_server::proto::rest_json_1::AwsRestJson1; use http::HeaderValue; use hyper::body::to_bytes; use pretty_assertions::assert_eq; @@ -175,7 +180,7 @@ mod tests { #[tokio::test] async fn request_middleware_chain_keeps_headers_changes() -> PyResult<()> { let locals = crate::tests::initialize(); - let mut middlewares = PyMiddlewares(vec![]); + let mut middlewares = PyMiddlewares::new::(vec![]); Python::with_gil(|py| { let middleware = PyModule::new(py, "middleware").unwrap(); @@ -212,11 +217,7 @@ def second_middleware(request: Request): })?; let result = middlewares - .run( - Request::builder().body(Body::from("")).unwrap(), - Protocol::RestJson1, - locals, - ) + .run(Request::builder().body(Body::from("")).unwrap(), locals) .await .unwrap(); assert_eq!( @@ -229,7 +230,7 @@ def second_middleware(request: Request): #[tokio::test] async fn request_middleware_return_response() -> PyResult<()> { let locals = crate::tests::initialize(); - let mut middlewares = PyMiddlewares(vec![]); + let mut middlewares = PyMiddlewares::new::(vec![]); Python::with_gil(|py| { let middleware = PyModule::new(py, "middleware").unwrap(); @@ -252,11 +253,7 @@ def middleware(request: Request): })?; let result = middlewares - .run( - Request::builder().body(Body::from("")).unwrap(), - Protocol::RestJson1, - locals, - ) + .run(Request::builder().body(Body::from("")).unwrap(), locals) .await .unwrap_err(); assert_eq!(result.status(), 200); @@ -268,7 +265,7 @@ def middleware(request: Request): #[tokio::test] async fn request_middleware_raise_middleware_exception() -> PyResult<()> { let locals = crate::tests::initialize(); - let mut middlewares = PyMiddlewares(vec![]); + let mut middlewares = PyMiddlewares::new::(vec![]); Python::with_gil(|py| { let middleware = PyModule::new(py, "middleware").unwrap(); @@ -291,11 +288,7 @@ def middleware(request: Request): })?; let result = middlewares - .run( - Request::builder().body(Body::from("")).unwrap(), - Protocol::RestJson1, - locals, - ) + .run(Request::builder().body(Body::from("")).unwrap(), locals) .await .unwrap_err(); assert_eq!(result.status(), 503); @@ -311,7 +304,7 @@ def middleware(request: Request): #[tokio::test] async fn request_middleware_raise_python_exception() -> PyResult<()> { let locals = crate::tests::initialize(); - let mut middlewares = PyMiddlewares(vec![]); + let mut middlewares = PyMiddlewares::new::(vec![]); Python::with_gil(|py| { let middleware = PyModule::from_code( @@ -333,11 +326,7 @@ def middleware(request): })?; let result = middlewares - .run( - Request::builder().body(Body::from("")).unwrap(), - Protocol::RestJson1, - locals, - ) + .run(Request::builder().body(Body::from("")).unwrap(), locals) .await .unwrap_err(); assert_eq!(result.status(), 500); diff --git a/rust-runtime/aws-smithy-http-server-python/src/middleware/layer.rs b/rust-runtime/aws-smithy-http-server-python/src/middleware/layer.rs index 73508541a2d..9dcc91b5b6f 100644 --- a/rust-runtime/aws-smithy-http-server-python/src/middleware/layer.rs +++ b/rust-runtime/aws-smithy-http-server-python/src/middleware/layer.rs @@ -5,69 +5,52 @@ //! Tower layer implementation of Python middleware handling. use std::{ + marker::PhantomData, pin::Pin, task::{Context, Poll}, }; use aws_smithy_http_server::{ body::{Body, BoxBody}, - protocols::Protocol, + response::IntoResponse, }; use futures::{ready, Future}; use http::{Request, Response}; use pin_project_lite::pin_project; -use pyo3::PyResult; use pyo3_asyncio::TaskLocals; use tower::{Layer, Service}; -use crate::{error::PyException, middleware::PyFuture, PyMiddlewares}; +use crate::{middleware::PyFuture, PyMiddlewareException, PyMiddlewares}; /// Tower [Layer] implementation of Python middleware handling. /// /// Middleware stored in the `handlers` attribute will be executed, in order, /// inside an async Tower middleware. #[derive(Debug, Clone)] -pub struct PyMiddlewareLayer { +pub struct PyMiddlewareLayer

{ handlers: PyMiddlewares, - protocol: Protocol, locals: TaskLocals, + _protocol: PhantomData

, } -impl PyMiddlewareLayer { - pub fn new( - handlers: PyMiddlewares, - protocol: &str, - locals: TaskLocals, - ) -> PyResult { - let protocol = match protocol { - "aws.protocols#restJson1" => Protocol::RestJson1, - "aws.protocols#restXml" => Protocol::RestXml, - "aws.protocols#awsjson10" => Protocol::AwsJson10, - "aws.protocols#awsjson11" => Protocol::AwsJson11, - _ => { - return Err(PyException::new_err(format!( - "Protocol {protocol} is not supported" - ))) - } - }; - Ok(Self { +impl

PyMiddlewareLayer

{ + pub fn new(handlers: PyMiddlewares, locals: TaskLocals) -> Self { + Self { handlers, - protocol, locals, - }) + _protocol: PhantomData, + } } } -impl Layer for PyMiddlewareLayer { +impl Layer for PyMiddlewareLayer

+where + PyMiddlewareException: IntoResponse

, +{ type Service = PyMiddlewareService; fn layer(&self, inner: S) -> Self::Service { - PyMiddlewareService::new( - inner, - self.handlers.clone(), - self.protocol, - self.locals.clone(), - ) + PyMiddlewareService::new(inner, self.handlers.clone(), self.locals.clone()) } } @@ -76,21 +59,14 @@ impl Layer for PyMiddlewareLayer { pub struct PyMiddlewareService { inner: S, handlers: PyMiddlewares, - protocol: Protocol, locals: TaskLocals, } impl PyMiddlewareService { - pub fn new( - inner: S, - handlers: PyMiddlewares, - protocol: Protocol, - locals: TaskLocals, - ) -> PyMiddlewareService { + pub fn new(inner: S, handlers: PyMiddlewares, locals: TaskLocals) -> PyMiddlewareService { Self { inner, handlers, - protocol, locals, } } @@ -113,7 +89,7 @@ where let clone = self.inner.clone(); // See https://docs.rs/tower/latest/tower/trait.Service.html#be-careful-when-cloning-inner-services let inner = std::mem::replace(&mut self.inner, clone); - let run = self.handlers.run(req, self.protocol, self.locals.clone()); + let run = self.handlers.run(req, self.locals.clone()); ResponseFuture { middleware: State::Running { run }, @@ -184,6 +160,7 @@ mod tests { use super::*; use aws_smithy_http_server::body::to_boxed; + use aws_smithy_http_server::proto::rest_json_1::AwsRestJson1; use pyo3::prelude::*; use tower::{Service, ServiceBuilder, ServiceExt}; @@ -234,11 +211,7 @@ def second_middleware(request: Request): })?; let mut service = ServiceBuilder::new() - .layer(PyMiddlewareLayer::new( - middlewares, - "aws.protocols#restJson1", - locals, - )?) + .layer(PyMiddlewareLayer::::new(middlewares, locals)) .service_fn(echo); let request = Request::get("/").body(Body::empty()).unwrap(); diff --git a/rust-runtime/aws-smithy-http-server-python/src/server.rs b/rust-runtime/aws-smithy-http-server-python/src/server.rs index fdff93b3981..ad3f189bbe1 100644 --- a/rust-runtime/aws-smithy-http-server-python/src/server.rs +++ b/rust-runtime/aws-smithy-http-server-python/src/server.rs @@ -63,8 +63,6 @@ pub trait PyApp: Clone + pyo3::IntoPy { fn middlewares(&mut self) -> &mut PyMiddlewares; - fn protocol(&self) -> &'static str; - /// Handle the graceful termination of Python workers by looping through all the /// active workers and calling `terminate()` on them. If termination fails, this /// method will try to `kill()` any failed worker.