milenkovicm opened a new pull request, #2754:
URL: https://github.com/apache/datafusion-ballista/pull/2754

   # Which issue does this PR close?
   
   Closes #.
   
   # Rationale for this change
   
   Today, all communication between the Python client and a Ballista cluster 
happens in Rust, inside `DistributedQueryExec`. That covers submitting the job, 
tracking its status, fetching results over Arrow Flight, and cancelling the 
job. Python users can't change how the cluster is reached (authentication 
headers, TLS, custom channels, result handling) without changing Rust code.
   
   This PR adds a second client written in Python. It sits beside the existing 
native client; nothing is replaced. Plans are still built and encoded in Rust, 
because that needs Ballista's logical extension codec. A thin Rust exec node, 
created during planning, passes the encoded query to a Python `BallistaClient`, 
which does all gRPC and Flight work. Users pick a client by choosing a session 
context, which also makes it easy to compare the two.
   
   # What changes are included in this PR?
   
   **Python client** (`python/python/ballista/client.py`)
   - `BallistaClient` submits jobs to the scheduler, tracks them by polling 
(pull) or by the `ExecuteQueryPush` status stream (push), and fetches results 
with `pyarrow.flight` `do_get`. The ticket is the same `Action::FetchPartition` 
protobuf the Rust client sends.
   - It also supports:
     - pipelined jobs: final-stage partitions are read concurrently, and a job 
failure stops the stream
     - Flight proxies, local and external
     - the scheduler version check
     - IO retries
     - cancelling the job when its results are closed before the job finishes
   - Subclasses can override `create_channel`, `call_metadata` and 
`create_flight_client`.
   - Options are resolved in this order: options passed to the client override 
the query's `ballista.*` settings, which override Ballista defaults.
   - Batches handed to Rust must have aligned buffers. On pyarrow 21 and later, 
Flight reads use `ensure_alignment`; older versions copy each batch.
   
   **Rust node and planner** (`python/src/python_query_exec.rs`)
   - `PythonDistributedQueryExec` encodes the query, calls 
`client.execute(params, schema)`, and streams results through the Arrow C 
stream interface on the blocking pool. Dropping the stream closes the job.
   - `PythonDistributedExplainAnalyzeExec` fetches job metrics through 
`client.job_metrics(job_id)`.
   - `PythonClientQueryPlanner` uses the same planning rules as 
`BallistaQueryPlanner`.
   - The new `BallistaPythonClientExtension` installs the planner and codecs 
through `SessionContext.with_extensions`.
   
   **Codec** (`python/src/codec.rs`)
   - Physical plans cross the datafusion-python FFI boundary as protobuf, and a 
Python object can't be serialized. A physical codec created with a client 
therefore decodes `DistributedQueryExecNode` / 
`DistributedExplainAnalyzeExecNode` into the Python-backed execs. A codec 
without a client, such as the one used by schedulers and executors started from 
Python, behaves as before. No `.proto` changes.
   
   **ballista-core**
   - `execute_query_params` is extracted from `DistributedQueryExec::execute`, 
so both clients build the same `ExecuteQueryParams`. Behaviour is unchanged.
   - `format_metrics_as_record_batch` is now public.
   
   **Python package**
   - New `BallistaPythonSessionContext`. `BallistaSessionContext` is unchanged.
   - New exports: `BallistaClient`, `BallistaJob`, `BallistaJobError`.
   - gRPC stubs generated from `ballista/core/proto` are committed under 
`ballista/proto/`. They are regenerated with `dev/generate_proto.sh`.
   
   **Build and CI**
   - New runtime dependencies: `grpcio>=1.85.1`, `protobuf>=7.35.1,<8`. 
`pyarrow` moves from a test dependency to a runtime one. The minimum versions 
match what the generated code checks at import time. `grpcio-tools` is pinned 
in the dev group so regenerated stubs are identical.
   - A CI step fails if the committed stubs are out of date. The stubs are 
excluded from ruff and from RAT.
   
   **Tests**
   - The `ctx` fixture in `test_context.py` now runs every context test against 
both clients.
   - New `test_client.py` covers:
     - custom client hooks
     - pull and push tracking
     - configuring the default client from the session config
     - reporting job failures
     - cancelling on close
     - realigning batches on older pyarrow
     - version compatibility
   - Pipelined execution was checked by hand against a `push-staged` scheduler, 
in both pull and push mode, with the same results as the native client. The 
in-process test cluster runs `pull-staged`, so pipelined mode is not covered by 
automated tests.
   
   Not yet done in the Python client:
   - `ballista.client.grpc_connect_timeout_seconds` and the HTTP/2 window size 
options are not mapped to gRPC options.
   - The job timing metrics the native client records (`job_execution_time_ms`, 
`job_scheduling_in_ms`, `total_query_time_ms`) are not reported.
   
   # Are there any user-facing changes?
   
   Yes, all additive:
   - `BallistaPythonSessionContext` and `BallistaClient` in the Python package. 
Existing `BallistaSessionContext` users see no change.
   - New runtime dependencies for the Python package: `grpcio`, `protobuf` and 
`pyarrow`.
   - Two new public functions in `ballista-core`: 
`execution_plans::execute_query_params` and 
`execution_plans::format_metrics_as_record_batch`.
   
   There are no breaking API changes and no wire or serialization format 
changes.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to