-
Notifications
You must be signed in to change notification settings - Fork 190
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
Python: map Python middlewares to Tower layers #1871
Conversation
A new generated diff is ready to view.
A new doc preview is ready to view. |
1b08bf5
to
29fe37d
Compare
A new generated diff is ready to view.
A new doc preview is ready to view. |
A new generated diff is ready to view.
A new doc preview is ready to view. |
a1cab3e
to
70c1826
Compare
A new generated diff is ready to view.
A new doc preview is ready to view. |
A new generated diff is ready to view.
A new doc preview is ready to view. |
c3a8df5
to
6154bc2
Compare
A new generated diff is ready to view.
A new doc preview is ready to view. |
A new generated diff is ready to view.
A new doc preview is ready to view. |
7340d64
to
a81def9
Compare
A new generated diff is ready to view.
A new doc preview is ready to view. |
...are/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt
Outdated
Show resolved
Hide resolved
...are/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt
Outdated
Show resolved
Hide resolved
...are/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt
Outdated
Show resolved
Hide resolved
def main(): | ||
def main() -> None: | ||
app.run(workers=1) |
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.
Do we need a separate main
function? 🤔
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 think it is not required but having a explicitly defined entry point is kinda useful when you want to setup your service via a supervisor or something
let middleware_err = Python::with_gil(|py| other.to_object(py).extract::<Self>(py)); | ||
match middleware_err { | ||
Ok(err) => err, | ||
Err(_) => Self::newpy(other.to_string(), None), |
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.
Here we probably want a log statement capturing the details of the exception that we failed to extract since it didn't match the one we expected.
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.
The error on the Err(_)
variant will always be 'TypeError' object cannot be converted to 'MiddlewareException'
here because it is a conversion error and the real error will be logged at https://github.com/awslabs/smithy-rs/blob/e12136563d734e3c1ea40d96a1705d3b1f5d9cbe/rust-runtime/aws-smithy-http-server-python/src/middleware/layer.rs#L124
rust-runtime/aws-smithy-http-server-python/src/middleware/error.rs
Outdated
Show resolved
Hide resolved
rust-runtime/aws-smithy-http-server-python/src/middleware/handler.rs
Outdated
Show resolved
Hide resolved
rust-runtime/aws-smithy-http-server-python/src/middleware/handler.rs
Outdated
Show resolved
Hide resolved
rust-runtime/aws-smithy-http-server-python/src/middleware/layer.rs
Outdated
Show resolved
Hide resolved
rust-runtime/aws-smithy-http-server-python/src/middleware/pytests/layer.rs
Show resolved
Hide resolved
A new generated diff is ready to view.
A new doc preview is ready to view. |
A new generated diff is ready to view.
A new doc preview is ready to view. |
A new generated diff is ready to view.
A new doc preview is ready to view. |
9047f46
to
e121365
Compare
fn keys(&self) -> PyResult<Vec<Self::Key>>; | ||
fn values(&self) -> PyResult<Vec<Self::Value>>; |
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'm wondering if this is a footgun.
In Python you'd expect iterating over an existing collection to be "free", while our implementation triggers a deep clone of the entire map.
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.e. as a Python developer, I wouldn't expect this:
for elem in map:
assert elem in elems
to trigger a deep clone of all elements in the map.
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 think this is a good first step, but me and Burak already talked about understanding what is needed to prevent the deep clone and borrow the map so that it becomes cheaper. I am not even sure if this is possible with the current PyO3 support.
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 don't we can if we are stuck with using HeaderMap
as is.
This would be less of an issue If both the header names and their values happened to be behind smart pointers.
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.
Btw, if you are already tracking this issue feel free to merge and we can revisit it later. But perhaps worth calling it out in the docs for those methods.
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've added comments to the related methods: c8bd368.
This would be less of an issue If both the header names and their values happened to be behind smart pointers.
We are converting them to String
s while crossing to Python: https://github.com/awslabs/smithy-rs/blob/c8bd36852b3be76914b5637f855a1e9e7a972571/rust-runtime/aws-smithy-http-server-python/src/middleware/header_map.rs#L56-L66
Co-authored-by: Luca Palmieri <[email protected]>
Co-authored-by: Matteo Bigoi <[email protected]>
76b2e07
to
385f133
Compare
A new generated diff is ready to view.
A new doc preview is ready to view. |
A new generated diff is ready to view.
A new doc preview is ready to view. |
Map pure Python middlewares to Tower layers so they can have same flexibility as pure Rust middlewares.
Pure Python middlewares will look like this:
so they will have total control over the execution flow. They can modify the request, return a response without calling the handler, apply timeout to the handler, modify the response returned by the handler etc.
TODOs
Provide a way to access to theContext
Request
Response
/cc @chadac @teruokun @PC-LoadLetter