-
Notifications
You must be signed in to change notification settings - Fork 681
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
[WIP] Make Rust flyteidl PyO3-ready #5525
base: flyrs
Are you sure you want to change the base?
Conversation
…` crate Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
…ding Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
flyteidl-rust
Python binding packageflyteidl-rust
binding
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## flyrs #5525 +/- ##
==========================================
+ Coverage 36.17% 36.51% +0.34%
==========================================
Files 1302 1302
Lines 109492 129155 +19663
==========================================
+ Hits 39606 47167 +7561
- Misses 65748 77850 +12102
Partials 4138 4138
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
flyteidl-rust
bindingflyteidl-rust
binding
} | ||
|
||
#[pyclass(subclass, name = "RawSynchronousFlyteClient")] | ||
pub struct RawSynchronousFlyteClient { |
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 entry point that should wrap all the gRPC service stubs.
} | ||
|
||
// #[macro_export] | ||
// macro_rules! concrete_generic_structure { |
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.
At present, we don't need to specify the concrete type for generics parameterization, since we output the wrapped FlyteRemote
as binding class instead of each gRPC stubs. So the macro oncrete_generic_structure
is commented out.
pub fn SerializeToString(&self) -> Result<Vec<u8>, crate::_flyteidl_rust::MessageEncodeError> | ||
{ | ||
// Bring `prost::Message` trait to scope here. Put it in outer impl block will leads to duplicated imports. | ||
use prost::Message; |
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.
Check here: tokio-rs/prost#525
|
||
#[pyclass] | ||
#[pyo3(name = "FlyteUserException", subclass, extends = pyo3::exceptions::PyException)] // or PyBaseException | ||
pub struct PyFlyteUserException {} |
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.
XREF on how to raise custom error from rust and catch them in python: PyO3/pyo3#4165
flyteidl-rust
bindingSigned-off-by: Austin Liu <austin362667@gmail.com> fmt & clippy Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
…e416bb750efd227e4f8b4302392c0d303 Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com> fixup workflow API & structure Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com> fix `--repository` `testpypi` Signed-off-by: Austin Liu <austin362667@gmail.com> fix `--repository` `testpypi` Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com> normalize path Signed-off-by: Austin Liu <austin362667@gmail.com> stringify path Signed-off-by: Austin Liu <austin362667@gmail.com> multi-string path Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com> fix glob Signed-off-by: Austin Liu <austin362667@gmail.com> fix glob Signed-off-by: Austin Liu <austin362667@gmail.com> fix glob Signed-off-by: Austin Liu <austin362667@gmail.com> fix glob Signed-off-by: Austin Liu <austin362667@gmail.com> fix glob Signed-off-by: Austin Liu <austin362667@gmail.com> fix syntax Signed-off-by: Austin Liu <austin362667@gmail.com> fix syntax Signed-off-by: Austin Liu <austin362667@gmail.com> fix glob Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com> specify minimum pyhton version to pypi Signed-off-by: Austin Liu <austin362667@gmail.com> specify minimum pyhton version to pypi Signed-off-by: Austin Liu <austin362667@gmail.com> specify minimum pyhton version to pypi Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com> fix testpypi url Signed-off-by: Austin Liu <austin362667@gmail.com> fix testpypi url Signed-off-by: Austin Liu <austin362667@gmail.com> fix testpypi url Signed-off-by: Austin Liu <austin362667@gmail.com> fix glob Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com> add MATURIN_REPOSITORY_URL Signed-off-by: Austin Liu <austin362667@gmail.com> add MATURIN_REPOSITORY_URL Signed-off-by: Austin Liu <austin362667@gmail.com> add MATURIN_REPOSITORY_URL Signed-off-by: Austin Liu <austin362667@gmail.com> add MATURIN_REPOSITORY_URL Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com> fmt Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
|
||
[project] | ||
name = "flyteidl" |
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.
We still need to keep flyteidl before migrating everything to flyteidl_rust. Could we create another file called pyproject-rust.toml
Creates a RawSynchronousFlyteClient based on destination endpoint that connects to Flyte gRPC Server. | ||
|
||
:param endpoint: destination endpoint of a RawSynchronousFlyteClient to be connect to. | ||
:return: a RawSynchronousFlyteClient instance with default platform configuration. |
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 to add methods here? (e.g. createTask
, createWorkflow
, etc). If so, I think we can do it in the follow-up PR.
@@ -0,0 +1,31 @@ | |||
// Copyright (c) 2015, Google Inc. |
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.
Could we add a README.md to the google/api directory to explain why we need these google protobuf files
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Signed-off-by: Austin Liu <austin362667@gmail.com>
Tracking issue
#5344
Why are the changes needed?
This pull request focuses on modifying the Rust flyteidl library to pave the way for the introduction of
flyteidl-rust
as a Python binding. The changes address issues raised in issues and serve as a foundation for the PR.What changes were proposed in this pull request?
Key Modifications:
Custom Code Generator:
Added a custom
tonic_builder
gRPC code generator. The code for this generator can be found in src/gen.rs. Will try to refactor intobuf
generator in follow-up PRs.Compile Well-Known Types:
Background:
#[pyclass]
attribute macro on our Rust structure. This macro implements thePyClass
trait for the underlying structure "under the hood".PyClass
trait for a structure from an external crate (likeprost_types
) can lead to orphan rule violations in our local crate. The Rust compiler will not permit implementation of traits for types outside of the crate where the type is defined. (This is known as the "orphan rule".)Avoiding Orphan Rules:
In some protobuf builders, like
tonic_builder
, there's an option to enable "compile well-known types". This forces the builder to compile well-known types (WKTs) directly using Rust primitive types instead of relying on external structures compiled from theprost_types
crate.Alternatives Considered:
One alternative is to create local wrappers around each external structure, as suggested by the PyO3 community. However, this solution becomes impractical when dealing with nested member fields within these structures. Because we still have to add
PyClass
trait all the way down to the nesting hierarchy. We'll elaborate more on gRPC client cases.implement PyClass Traits for
Box<T>
:T
already has PyClass Traits.Box<T>
needs but does not have PyClass Traits.For example, in
flyteidl.core.rs
,Box<T>
:LiteralType
,Literal
,Union
,Scalar
,ConjunctionExpression
,BooleanExpression
,IfBlock
,BranchNode
,ArrayNode
, a total of 9 types will be on the heap.What situations will be converted to boxes?
Recursive types, such as
ArrayNode
, can hold references to other Nodes and are converted toArrayNode {node: Option<Box<Node>>, ...}
.This poses a challenge for PyO3, as it requires a PyClass to hold a reference to another PyClass. This is a Rust Non-lifetime-free issue.
While this PR supports
Cell<T>
, but didn't supportBox<T>
, it also highlights the difficulties of supportingBox<T>
.The PyO3 roadmap on addressing these issue seems like this way.
Solution:
Introduce conversion implementations and lifetime markers for the 9 types that use Box to prevent refs from outliving. For example, for Box, implement these two conversion traits instead of directly adding PyClass traits to Box:
Prevents references from outliving their intended lifetime, ensuring memory safety and preventing potential memory leaks.
IntoRequest Trait:
For cases like following example,
Based on Types implementing this trait can be used as arguments to client RPC
We can directly pass them to gRPC services, like:
Tuple Variants in Complex Enum: PyO3 supports tuple enum variants after version v0.22.0
Python submodules: Use latest feature Declarative modules introduced in version v0.22.0.
Optional: Concretize Generic Types
Challenges:
GenericType<i32>
,GenericType<f64>
, would have to have a different Python type object. This is an infinite set, and code would need to be generated for each instantiation. It isn't trivia for PyO3 to support.The Macro Solution
Define Concrete Structures: We can create new structures (AdminStub in the example) with predefined concrete types for each gRPC stub. This allows specifying the exact types needed for PyO3 interaction.
Using Macros for Automation: The following example leverages a Rust macro named
concrete_generic_structure!
to automate the creation of these concrete structures. It takes arguments for the structure name, the generic type it wraps, and the concrete type used. Additionally, it allows defining methods associated with the stub, specifying the request and response types.The provided code demonstrates how the macro is used to create an
AdminStub
structure. This structure wraps theAdminServiceClient
generic type, and specifiestonic::transport::Channel
as the concrete type for the channel. Additionally, it defines two methods (create_task
andget_task
) with their specific request and response types.Trade-offs:
How was this patch tested?
Setup process
Screenshots
Check all the applicable boxes
Related PRs
flyteorg/flytekit#2536
Docs link