From 25fa26f7261fe380f01da0112cd733d810f8761e Mon Sep 17 00:00:00 2001
From: David Li
Date: Mon, 7 Aug 2023 13:05:39 -0400
Subject: [PATCH] Python
---
python/pyarrow/_flight.pyx | 84 +++++++++++++++++++++
python/pyarrow/includes/libarrow_flight.pxd | 4 +
python/pyarrow/src/arrow/python/flight.cc | 25 ++++++
python/pyarrow/src/arrow/python/flight.h | 9 +++
4 files changed, 122 insertions(+)
diff --git a/python/pyarrow/_flight.pyx b/python/pyarrow/_flight.pyx
index 0572ed77b40ef..79c42744f3dbd 100644
--- a/python/pyarrow/_flight.pyx
+++ b/python/pyarrow/_flight.pyx
@@ -24,6 +24,11 @@ import time
import warnings
import weakref
+try:
+ import anyio
+except ImportError:
+ anyio = None
+
from cython.operator cimport dereference as deref
from cython.operator cimport postincrement
from libcpp cimport bool as c_bool
@@ -1219,6 +1224,80 @@ cdef class FlightMetadataWriter(_Weakrefable):
check_flight_status(self.writer.get().WriteMetadata(deref(buf)))
+class AsyncCall:
+ # General strategy: create an anyio Event, tell the future to wake it on success/error
+ def __init__(self):
+ self.event = anyio.Event()
+ self.result = None
+ self.exception = None
+
+ async def wait(self) -> object:
+ print("Wait event")
+ import asyncio
+ self._loop = asyncio.get_running_loop()
+ await self.event.wait()
+ print("Waiting event")
+ if self.exception:
+ raise self.exception
+ return self.result
+
+
+cdef class AsyncFlightClient:
+ """
+ The async interface of a FlightClient.
+
+ This interface is EXPERIMENTAL.
+ """
+
+ cdef:
+ FlightClient client
+
+ def __init__(self, FlightClient client) -> None:
+ self.client = client
+
+ # TODO: return type that allows you to optionally get response
+ # headers/trailers - maybe a runtime option? since we'd have to copy all
+ # of them. or just always copy them? moot point for now since not yet
+ # exposed.
+ async def get_flight_info(
+ self,
+ descriptor: FlightDescriptor,
+ *,
+ options: FlightCallOptions = None,
+ ):
+ call = AsyncCall()
+ self._get_flight_info(call, descriptor, options)
+ return await call.wait()
+
+ cdef _get_flight_info(self, call, descriptor, options):
+ cdef:
+ CFlightCallOptions* c_options = \
+ FlightCallOptions.unwrap(options)
+ CFlightDescriptor c_descriptor = \
+ FlightDescriptor.unwrap(descriptor)
+ function[cb_client_async_get_flight_info] callback = \
+ &_client_async_get_flight_info
+
+ with nogil:
+ CAsyncGetFlightInfo(self.client.client.get(), deref(c_options), c_descriptor, call, callback)
+
+
+cdef void _client_async_get_flight_info(void* self, CFlightInfo* info, const CStatus& status):
+ cdef FlightInfo result = FlightInfo.__new__(FlightInfo)
+ call =