mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-04-23 02:40:43 +00:00
351 lines
14 KiB
C++
351 lines
14 KiB
C++
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "arrow/flight/api.h"
|
|
#include "arrow/ipc/dictionary.h"
|
|
#include "arrow/python/common.h"
|
|
|
|
#if defined(_WIN32) || defined(__CYGWIN__) // Windows
|
|
#if defined(_MSC_VER)
|
|
#pragma warning(disable : 4251)
|
|
#else
|
|
#pragma GCC diagnostic ignored "-Wattributes"
|
|
#endif
|
|
|
|
#ifdef ARROW_STATIC
|
|
#define ARROW_PYFLIGHT_EXPORT
|
|
#elif defined(ARROW_PYFLIGHT_EXPORTING)
|
|
#define ARROW_PYFLIGHT_EXPORT __declspec(dllexport)
|
|
#else
|
|
#define ARROW_PYFLIGHT_EXPORT __declspec(dllimport)
|
|
#endif
|
|
|
|
#else // Not Windows
|
|
#ifndef ARROW_PYFLIGHT_EXPORT
|
|
#define ARROW_PYFLIGHT_EXPORT __attribute__((visibility("default")))
|
|
#endif
|
|
#endif // Non-Windows
|
|
|
|
namespace arrow {
|
|
|
|
namespace py {
|
|
|
|
namespace flight {
|
|
|
|
ARROW_PYFLIGHT_EXPORT
|
|
extern const char* kPyServerMiddlewareName;
|
|
|
|
/// \brief A table of function pointers for calling from C++ into
|
|
/// Python.
|
|
class ARROW_PYFLIGHT_EXPORT PyFlightServerVtable {
|
|
public:
|
|
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
|
|
const arrow::flight::Criteria*,
|
|
std::unique_ptr<arrow::flight::FlightListing>*)>
|
|
list_flights;
|
|
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
|
|
const arrow::flight::FlightDescriptor&,
|
|
std::unique_ptr<arrow::flight::FlightInfo>*)>
|
|
get_flight_info;
|
|
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
|
|
const arrow::flight::FlightDescriptor&,
|
|
std::unique_ptr<arrow::flight::SchemaResult>*)>
|
|
get_schema;
|
|
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
|
|
const arrow::flight::Ticket&,
|
|
std::unique_ptr<arrow::flight::FlightDataStream>*)>
|
|
do_get;
|
|
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
|
|
std::unique_ptr<arrow::flight::FlightMessageReader>,
|
|
std::unique_ptr<arrow::flight::FlightMetadataWriter>)>
|
|
do_put;
|
|
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
|
|
std::unique_ptr<arrow::flight::FlightMessageReader>,
|
|
std::unique_ptr<arrow::flight::FlightMessageWriter>)>
|
|
do_exchange;
|
|
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
|
|
const arrow::flight::Action&,
|
|
std::unique_ptr<arrow::flight::ResultStream>*)>
|
|
do_action;
|
|
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
|
|
std::vector<arrow::flight::ActionType>*)>
|
|
list_actions;
|
|
};
|
|
|
|
class ARROW_PYFLIGHT_EXPORT PyServerAuthHandlerVtable {
|
|
public:
|
|
std::function<Status(PyObject*, arrow::flight::ServerAuthSender*,
|
|
arrow::flight::ServerAuthReader*)>
|
|
authenticate;
|
|
std::function<Status(PyObject*, const std::string&, std::string*)> is_valid;
|
|
};
|
|
|
|
class ARROW_PYFLIGHT_EXPORT PyClientAuthHandlerVtable {
|
|
public:
|
|
std::function<Status(PyObject*, arrow::flight::ClientAuthSender*,
|
|
arrow::flight::ClientAuthReader*)>
|
|
authenticate;
|
|
std::function<Status(PyObject*, std::string*)> get_token;
|
|
};
|
|
|
|
/// \brief A helper to implement an auth mechanism in Python.
|
|
class ARROW_PYFLIGHT_EXPORT PyServerAuthHandler
|
|
: public arrow::flight::ServerAuthHandler {
|
|
public:
|
|
explicit PyServerAuthHandler(PyObject* handler,
|
|
const PyServerAuthHandlerVtable& vtable);
|
|
Status Authenticate(arrow::flight::ServerAuthSender* outgoing,
|
|
arrow::flight::ServerAuthReader* incoming) override;
|
|
Status IsValid(const std::string& token, std::string* peer_identity) override;
|
|
|
|
private:
|
|
OwnedRefNoGIL handler_;
|
|
PyServerAuthHandlerVtable vtable_;
|
|
};
|
|
|
|
/// \brief A helper to implement an auth mechanism in Python.
|
|
class ARROW_PYFLIGHT_EXPORT PyClientAuthHandler
|
|
: public arrow::flight::ClientAuthHandler {
|
|
public:
|
|
explicit PyClientAuthHandler(PyObject* handler,
|
|
const PyClientAuthHandlerVtable& vtable);
|
|
Status Authenticate(arrow::flight::ClientAuthSender* outgoing,
|
|
arrow::flight::ClientAuthReader* incoming) override;
|
|
Status GetToken(std::string* token) override;
|
|
|
|
private:
|
|
OwnedRefNoGIL handler_;
|
|
PyClientAuthHandlerVtable vtable_;
|
|
};
|
|
|
|
class ARROW_PYFLIGHT_EXPORT PyFlightServer : public arrow::flight::FlightServerBase {
|
|
public:
|
|
explicit PyFlightServer(PyObject* server, const PyFlightServerVtable& vtable);
|
|
|
|
// Like Serve(), but set up signals and invoke Python signal handlers
|
|
// if necessary. This function may return with a Python exception set.
|
|
Status ServeWithSignals();
|
|
|
|
Status ListFlights(const arrow::flight::ServerCallContext& context,
|
|
const arrow::flight::Criteria* criteria,
|
|
std::unique_ptr<arrow::flight::FlightListing>* listings) override;
|
|
Status GetFlightInfo(const arrow::flight::ServerCallContext& context,
|
|
const arrow::flight::FlightDescriptor& request,
|
|
std::unique_ptr<arrow::flight::FlightInfo>* info) override;
|
|
Status GetSchema(const arrow::flight::ServerCallContext& context,
|
|
const arrow::flight::FlightDescriptor& request,
|
|
std::unique_ptr<arrow::flight::SchemaResult>* result) override;
|
|
Status DoGet(const arrow::flight::ServerCallContext& context,
|
|
const arrow::flight::Ticket& request,
|
|
std::unique_ptr<arrow::flight::FlightDataStream>* stream) override;
|
|
Status DoPut(const arrow::flight::ServerCallContext& context,
|
|
std::unique_ptr<arrow::flight::FlightMessageReader> reader,
|
|
std::unique_ptr<arrow::flight::FlightMetadataWriter> writer) override;
|
|
Status DoExchange(const arrow::flight::ServerCallContext& context,
|
|
std::unique_ptr<arrow::flight::FlightMessageReader> reader,
|
|
std::unique_ptr<arrow::flight::FlightMessageWriter> writer) override;
|
|
Status DoAction(const arrow::flight::ServerCallContext& context,
|
|
const arrow::flight::Action& action,
|
|
std::unique_ptr<arrow::flight::ResultStream>* result) override;
|
|
Status ListActions(const arrow::flight::ServerCallContext& context,
|
|
std::vector<arrow::flight::ActionType>* actions) override;
|
|
|
|
private:
|
|
OwnedRefNoGIL server_;
|
|
PyFlightServerVtable vtable_;
|
|
};
|
|
|
|
/// \brief A callback that obtains the next result from a Flight action.
|
|
typedef std::function<Status(PyObject*, std::unique_ptr<arrow::flight::Result>*)>
|
|
PyFlightResultStreamCallback;
|
|
|
|
/// \brief A ResultStream built around a Python callback.
|
|
class ARROW_PYFLIGHT_EXPORT PyFlightResultStream : public arrow::flight::ResultStream {
|
|
public:
|
|
/// \brief Construct a FlightResultStream from a Python object and callback.
|
|
/// Must only be called while holding the GIL.
|
|
explicit PyFlightResultStream(PyObject* generator,
|
|
PyFlightResultStreamCallback callback);
|
|
arrow::Result<std::unique_ptr<arrow::flight::Result>> Next() override;
|
|
|
|
private:
|
|
OwnedRefNoGIL generator_;
|
|
PyFlightResultStreamCallback callback_;
|
|
};
|
|
|
|
/// \brief A wrapper around a FlightDataStream that keeps alive a
|
|
/// Python object backing it.
|
|
class ARROW_PYFLIGHT_EXPORT PyFlightDataStream : public arrow::flight::FlightDataStream {
|
|
public:
|
|
/// \brief Construct a FlightDataStream from a Python object and underlying stream.
|
|
/// Must only be called while holding the GIL.
|
|
explicit PyFlightDataStream(PyObject* data_source,
|
|
std::unique_ptr<arrow::flight::FlightDataStream> stream);
|
|
|
|
std::shared_ptr<Schema> schema() override;
|
|
arrow::Result<arrow::flight::FlightPayload> GetSchemaPayload() override;
|
|
arrow::Result<arrow::flight::FlightPayload> Next() override;
|
|
|
|
private:
|
|
OwnedRefNoGIL data_source_;
|
|
std::unique_ptr<arrow::flight::FlightDataStream> stream_;
|
|
};
|
|
|
|
class ARROW_PYFLIGHT_EXPORT PyServerMiddlewareFactory
|
|
: public arrow::flight::ServerMiddlewareFactory {
|
|
public:
|
|
/// \brief A callback to create the middleware instance in Python
|
|
typedef std::function<Status(
|
|
PyObject*, const arrow::flight::CallInfo& info,
|
|
const arrow::flight::CallHeaders& incoming_headers,
|
|
std::shared_ptr<arrow::flight::ServerMiddleware>* middleware)>
|
|
StartCallCallback;
|
|
|
|
/// \brief Must only be called while holding the GIL.
|
|
explicit PyServerMiddlewareFactory(PyObject* factory, StartCallCallback start_call);
|
|
|
|
Status StartCall(const arrow::flight::CallInfo& info,
|
|
const arrow::flight::CallHeaders& incoming_headers,
|
|
std::shared_ptr<arrow::flight::ServerMiddleware>* middleware) override;
|
|
|
|
private:
|
|
OwnedRefNoGIL factory_;
|
|
StartCallCallback start_call_;
|
|
};
|
|
|
|
class ARROW_PYFLIGHT_EXPORT PyServerMiddleware : public arrow::flight::ServerMiddleware {
|
|
public:
|
|
typedef std::function<Status(PyObject*,
|
|
arrow::flight::AddCallHeaders* outgoing_headers)>
|
|
SendingHeadersCallback;
|
|
typedef std::function<Status(PyObject*, const Status& status)> CallCompletedCallback;
|
|
|
|
struct Vtable {
|
|
SendingHeadersCallback sending_headers;
|
|
CallCompletedCallback call_completed;
|
|
};
|
|
|
|
/// \brief Must only be called while holding the GIL.
|
|
explicit PyServerMiddleware(PyObject* middleware, Vtable vtable);
|
|
|
|
void SendingHeaders(arrow::flight::AddCallHeaders* outgoing_headers) override;
|
|
void CallCompleted(const Status& status) override;
|
|
std::string name() const override;
|
|
/// \brief Get the underlying Python object.
|
|
PyObject* py_object() const;
|
|
|
|
private:
|
|
OwnedRefNoGIL middleware_;
|
|
Vtable vtable_;
|
|
};
|
|
|
|
class ARROW_PYFLIGHT_EXPORT PyClientMiddlewareFactory
|
|
: public arrow::flight::ClientMiddlewareFactory {
|
|
public:
|
|
/// \brief A callback to create the middleware instance in Python
|
|
typedef std::function<Status(
|
|
PyObject*, const arrow::flight::CallInfo& info,
|
|
std::unique_ptr<arrow::flight::ClientMiddleware>* middleware)>
|
|
StartCallCallback;
|
|
|
|
/// \brief Must only be called while holding the GIL.
|
|
explicit PyClientMiddlewareFactory(PyObject* factory, StartCallCallback start_call);
|
|
|
|
void StartCall(const arrow::flight::CallInfo& info,
|
|
std::unique_ptr<arrow::flight::ClientMiddleware>* middleware) override;
|
|
|
|
private:
|
|
OwnedRefNoGIL factory_;
|
|
StartCallCallback start_call_;
|
|
};
|
|
|
|
class ARROW_PYFLIGHT_EXPORT PyClientMiddleware : public arrow::flight::ClientMiddleware {
|
|
public:
|
|
typedef std::function<Status(PyObject*,
|
|
arrow::flight::AddCallHeaders* outgoing_headers)>
|
|
SendingHeadersCallback;
|
|
typedef std::function<Status(PyObject*,
|
|
const arrow::flight::CallHeaders& incoming_headers)>
|
|
ReceivedHeadersCallback;
|
|
typedef std::function<Status(PyObject*, const Status& status)> CallCompletedCallback;
|
|
|
|
struct Vtable {
|
|
SendingHeadersCallback sending_headers;
|
|
ReceivedHeadersCallback received_headers;
|
|
CallCompletedCallback call_completed;
|
|
};
|
|
|
|
/// \brief Must only be called while holding the GIL.
|
|
explicit PyClientMiddleware(PyObject* factory, Vtable vtable);
|
|
|
|
void SendingHeaders(arrow::flight::AddCallHeaders* outgoing_headers) override;
|
|
void ReceivedHeaders(const arrow::flight::CallHeaders& incoming_headers) override;
|
|
void CallCompleted(const Status& status) override;
|
|
|
|
private:
|
|
OwnedRefNoGIL middleware_;
|
|
Vtable vtable_;
|
|
};
|
|
|
|
/// \brief A callback that obtains the next payload from a Flight result stream.
|
|
typedef std::function<Status(PyObject*, arrow::flight::FlightPayload*)>
|
|
PyGeneratorFlightDataStreamCallback;
|
|
|
|
/// \brief A FlightDataStream built around a Python callback.
|
|
class ARROW_PYFLIGHT_EXPORT PyGeneratorFlightDataStream
|
|
: public arrow::flight::FlightDataStream {
|
|
public:
|
|
/// \brief Construct a FlightDataStream from a Python object and underlying stream.
|
|
/// Must only be called while holding the GIL.
|
|
explicit PyGeneratorFlightDataStream(PyObject* generator,
|
|
std::shared_ptr<arrow::Schema> schema,
|
|
PyGeneratorFlightDataStreamCallback callback,
|
|
const ipc::IpcWriteOptions& options);
|
|
std::shared_ptr<Schema> schema() override;
|
|
arrow::Result<arrow::flight::FlightPayload> GetSchemaPayload() override;
|
|
arrow::Result<arrow::flight::FlightPayload> Next() override;
|
|
|
|
private:
|
|
OwnedRefNoGIL generator_;
|
|
std::shared_ptr<arrow::Schema> schema_;
|
|
ipc::DictionaryFieldMapper mapper_;
|
|
ipc::IpcWriteOptions options_;
|
|
PyGeneratorFlightDataStreamCallback callback_;
|
|
};
|
|
|
|
ARROW_PYFLIGHT_EXPORT
|
|
Status CreateFlightInfo(const std::shared_ptr<arrow::Schema>& schema,
|
|
const arrow::flight::FlightDescriptor& descriptor,
|
|
const std::vector<arrow::flight::FlightEndpoint>& endpoints,
|
|
int64_t total_records, int64_t total_bytes,
|
|
std::unique_ptr<arrow::flight::FlightInfo>* out);
|
|
|
|
/// \brief Create a SchemaResult from schema.
|
|
ARROW_PYFLIGHT_EXPORT
|
|
Status CreateSchemaResult(const std::shared_ptr<arrow::Schema>& schema,
|
|
std::unique_ptr<arrow::flight::SchemaResult>* out);
|
|
|
|
} // namespace flight
|
|
} // namespace py
|
|
} // namespace arrow
|