-
Notifications
You must be signed in to change notification settings - Fork 196
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Python: Add tests and fix the issues with
Timestamp
and ByteStream
(
#2431) * Add `timestamp` type test and fix the conversion error * Add some tests for `ByteStream` and fix async issues * Use `__anext__` method instead of `anext` --------- Co-authored-by: Matteo Bigoi <[email protected]>
- Loading branch information
Showing
7 changed files
with
306 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
151 changes: 151 additions & 0 deletions
151
rust-runtime/aws-smithy-http-server-python/src/pytests/bytestream.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
use std::io; | ||
|
||
use futures::StreamExt; | ||
use futures_util::stream; | ||
use hyper::Body; | ||
use pyo3::{prelude::*, py_run}; | ||
|
||
use aws_smithy_http::body::SdkBody; | ||
use aws_smithy_http_server_python::types::ByteStream; | ||
|
||
#[pyo3_asyncio::tokio::test] | ||
fn consuming_stream_on_python_synchronously() -> PyResult<()> { | ||
let bytestream = streaming_bytestream_from_vec(vec!["hello", " ", "world"]); | ||
Python::with_gil(|py| { | ||
let bytestream = bytestream.into_py(py); | ||
py_run!( | ||
py, | ||
bytestream, | ||
r#" | ||
assert next(bytestream) == b"hello" | ||
assert next(bytestream) == b" " | ||
assert next(bytestream) == b"world" | ||
try: | ||
next(bytestream) | ||
assert False, "iteration should stop by now" | ||
except StopIteration: | ||
pass | ||
"# | ||
); | ||
Ok(()) | ||
}) | ||
} | ||
|
||
#[pyo3_asyncio::tokio::test] | ||
fn consuming_stream_on_python_synchronously_with_loop() -> PyResult<()> { | ||
let bytestream = streaming_bytestream_from_vec(vec!["hello", " ", "world"]); | ||
Python::with_gil(|py| { | ||
let bytestream = bytestream.into_py(py); | ||
py_run!( | ||
py, | ||
bytestream, | ||
r#" | ||
total = [] | ||
for chunk in bytestream: | ||
total.append(chunk) | ||
assert total == [b"hello", b" ", b"world"] | ||
"# | ||
); | ||
Ok(()) | ||
}) | ||
} | ||
|
||
#[pyo3_asyncio::tokio::test] | ||
fn consuming_stream_on_python_asynchronously() -> PyResult<()> { | ||
let bytestream = streaming_bytestream_from_vec(vec!["hello", " ", "world"]); | ||
Python::with_gil(|py| { | ||
let bytestream = bytestream.into_py(py); | ||
py_run!( | ||
py, | ||
bytestream, | ||
r#" | ||
import asyncio | ||
async def main(bytestream): | ||
assert await bytestream.__anext__() == b"hello" | ||
assert await bytestream.__anext__() == b" " | ||
assert await bytestream.__anext__() == b"world" | ||
try: | ||
await bytestream.__anext__() | ||
assert False, "iteration should stop by now" | ||
except StopAsyncIteration: | ||
pass | ||
asyncio.run(main(bytestream)) | ||
"# | ||
); | ||
Ok(()) | ||
}) | ||
} | ||
|
||
#[pyo3_asyncio::tokio::test] | ||
fn consuming_stream_on_python_asynchronously_with_loop() -> PyResult<()> { | ||
let bytestream = streaming_bytestream_from_vec(vec!["hello", " ", "world"]); | ||
Python::with_gil(|py| { | ||
let bytestream = bytestream.into_py(py); | ||
py_run!( | ||
py, | ||
bytestream, | ||
r#" | ||
import asyncio | ||
async def main(bytestream): | ||
total = [] | ||
async for chunk in bytestream: | ||
total.append(chunk) | ||
assert total == [b"hello", b" ", b"world"] | ||
asyncio.run(main(bytestream)) | ||
"# | ||
); | ||
Ok(()) | ||
}) | ||
} | ||
|
||
#[pyo3_asyncio::tokio::test] | ||
async fn streaming_back_to_rust_from_python() -> PyResult<()> { | ||
let bytestream = streaming_bytestream_from_vec(vec!["hello", " ", "world"]); | ||
let py_stream = Python::with_gil(|py| { | ||
let module = PyModule::from_code( | ||
py, | ||
r#" | ||
async def handler(bytestream): | ||
async for chunk in bytestream: | ||
yield "🐍 " + chunk.decode("utf-8") | ||
yield "Hello from Python!" | ||
"#, | ||
"", | ||
"", | ||
)?; | ||
let handler = module.getattr("handler")?; | ||
let output = handler.call1((bytestream,))?; | ||
Ok::<_, PyErr>(pyo3_asyncio::tokio::into_stream_v2(output)) | ||
})??; | ||
|
||
let mut py_stream = py_stream.map(|v| Python::with_gil(|py| v.extract::<String>(py).unwrap())); | ||
|
||
assert_eq!(py_stream.next().await, Some("🐍 hello".to_string())); | ||
assert_eq!(py_stream.next().await, Some("🐍 ".to_string())); | ||
assert_eq!(py_stream.next().await, Some("🐍 world".to_string())); | ||
assert_eq!( | ||
py_stream.next().await, | ||
Some("Hello from Python!".to_string()) | ||
); | ||
assert_eq!(py_stream.next().await, None); | ||
|
||
Ok(()) | ||
} | ||
|
||
fn streaming_bytestream_from_vec(chunks: Vec<&'static str>) -> ByteStream { | ||
let stream = stream::iter(chunks.into_iter().map(|v| Ok::<_, io::Error>(v))); | ||
let body = Body::wrap_stream(stream); | ||
ByteStream::new(SdkBody::from(body)) | ||
} |
11 changes: 11 additions & 0 deletions
11
rust-runtime/aws-smithy-http-server-python/src/pytests/harness.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#[pyo3_asyncio::tokio::main] | ||
async fn main() -> pyo3::PyResult<()> { | ||
pyo3_asyncio::testing::main().await | ||
} | ||
|
||
mod bytestream; |
Oops, something went wrong.