This is an automated email from the ASF dual-hosted git repository.
lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git
The following commit(s) were added to refs/heads/main by this push:
new d6eb01b feat(python): add enums for common options (#513)
d6eb01b is described below
commit d6eb01bcfad04e05929c9adf82b093d4ab08cf49
Author: David Li <[email protected]>
AuthorDate: Thu Mar 16 14:33:45 2023 -0400
feat(python): add enums for common options (#513)
Fixes #512.
---
.github/workflows/packaging.yml | 6 +-
...driver_sqlite.rst => adbc_driver_flightsql.rst} | 16 +--
docs/source/python/api/adbc_driver_manager.rst | 12 +++
docs/source/python/api/adbc_driver_sqlite.rst | 4 +-
docs/source/python/api/index.rst | 2 +
.../adbc_driver_flightsql/__init__.py | 112 ++++++++++++++++++++-
python/adbc_driver_flightsql/tests/conftest.py | 8 +-
.../adbc_driver_flightsql/tests/test_lowlevel.py | 14 +++
.../adbc_driver_manager/__init__.py | 43 +++++++-
.../adbc_driver_manager/_lib.pyx | 16 ++-
.../adbc_driver_sqlite/__init__.py | 14 ++-
python/adbc_driver_sqlite/tests/test_lowlevel.py | 13 +++
12 files changed, 237 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml
index 0b426a1..d990fb9 100644
--- a/.github/workflows/packaging.yml
+++ b/.github/workflows/packaging.yml
@@ -400,7 +400,8 @@ jobs:
name: "Python ${{ matrix.arch }} Conda"
runs-on: macos-latest
# No need for Conda packages during release
- if: "!startsWith(github.ref, 'refs/tags/')"
+ # TODO(apache/arrow-adbc#468): re-enable
+ if: false
needs:
- source
strategy:
@@ -872,7 +873,8 @@ jobs:
if: github.ref == 'refs/heads/main' && (github.event.schedule ||
inputs.upload_artifacts)
needs:
- python-conda-linux
- - python-conda-macos
+ # TODO(apache/arrow-adbc#468): re-enable
+ # - python-conda-macos
steps:
- uses: actions/checkout@v3
with:
diff --git a/docs/source/python/api/adbc_driver_sqlite.rst
b/docs/source/python/api/adbc_driver_flightsql.rst
similarity index 78%
copy from docs/source/python/api/adbc_driver_sqlite.rst
copy to docs/source/python/api/adbc_driver_flightsql.rst
index 49aa566..bbcdb59 100644
--- a/docs/source/python/api/adbc_driver_sqlite.rst
+++ b/docs/source/python/api/adbc_driver_flightsql.rst
@@ -17,20 +17,20 @@
.. default-domain:: py
-======================
-``adbc_driver_sqlite``
-======================
+=========================
+``adbc_driver_flightsql``
+=========================
Low-Level API
=============
-.. automodule:: adbc_driver_sqlite
-
-.. autofunction:: adbc_driver_sqlite.connect
+.. automodule:: adbc_driver_flightsql
+ :members:
+ :undoc-members:
DBAPI 2.0 API
=============
-.. automodule:: adbc_driver_sqlite.dbapi
+.. automodule:: adbc_driver_flightsql.dbapi
-.. autofunction:: adbc_driver_sqlite.dbapi.connect
+.. autofunction:: adbc_driver_flightsql.dbapi.connect
diff --git a/docs/source/python/api/adbc_driver_manager.rst
b/docs/source/python/api/adbc_driver_manager.rst
index dfa9fe8..c0d22b6 100644
--- a/docs/source/python/api/adbc_driver_manager.rst
+++ b/docs/source/python/api/adbc_driver_manager.rst
@@ -35,6 +35,18 @@ Constants & Enums
.. autoclass:: adbc_driver_manager.GetObjectsDepth
:members:
+.. autoclass:: adbc_driver_manager.ConnectionOptions
+ :members:
+ :undoc-members:
+
+.. autoclass:: adbc_driver_manager.DatabaseOptions
+ :members:
+ :undoc-members:
+
+.. autoclass:: adbc_driver_manager.StatementOptions
+ :members:
+ :undoc-members:
+
.. XXX: Sphinx doesn't seem to be able to parse docstrings out of
Cython code, so put the descriptions here instead.
diff --git a/docs/source/python/api/adbc_driver_sqlite.rst
b/docs/source/python/api/adbc_driver_sqlite.rst
index 49aa566..91e8e5d 100644
--- a/docs/source/python/api/adbc_driver_sqlite.rst
+++ b/docs/source/python/api/adbc_driver_sqlite.rst
@@ -25,8 +25,8 @@ Low-Level API
=============
.. automodule:: adbc_driver_sqlite
-
-.. autofunction:: adbc_driver_sqlite.connect
+ :members:
+ :undoc-members:
DBAPI 2.0 API
=============
diff --git a/docs/source/python/api/index.rst b/docs/source/python/api/index.rst
index 89afe14..527d88a 100644
--- a/docs/source/python/api/index.rst
+++ b/docs/source/python/api/index.rst
@@ -23,5 +23,7 @@ Python API Reference
:maxdepth: 1
adbc_driver_manager
+
+ adbc_driver_flightsql
adbc_driver_postgresql
adbc_driver_sqlite
diff --git a/python/adbc_driver_flightsql/adbc_driver_flightsql/__init__.py
b/python/adbc_driver_flightsql/adbc_driver_flightsql/__init__.py
index c6a9342..f4e9ddf 100644
--- a/python/adbc_driver_flightsql/adbc_driver_flightsql/__init__.py
+++ b/python/adbc_driver_flightsql/adbc_driver_flightsql/__init__.py
@@ -15,14 +15,122 @@
# specific language governing permissions and limitations
# under the License.
+"""Low-level ADBC bindings for the Flight SQL driver."""
+
+import enum
import functools
import typing
import adbc_driver_manager
-from ._version import __version__
+from ._version import __version__ # noqa:F401
+
+__all__ = [
+ "ConnectionOptions",
+ "DatabaseOptions",
+ "StatementOptions",
+ "connect",
+]
+
+
+class DatabaseOptions(enum.Enum):
+ """Database options specific to the Flight SQL driver."""
+
+ #: The authorization header to use for requests.
+ AUTHORIZATION_HEADER = "adbc.flight.sql.authorization_header"
+ #: Enable mTLS and use these PEM-encoded certificates.
+ MTLS_CERT_CHAIN = "adbc.flight.sql.client_option.mtls_cert_chain"
+ #: Enable mTLS and use this PEM-encoded private key.
+ MTLS_PRIVATE_KEY = "adbc.flight.sql.client_option.mtls_private_key"
+ #: Add an arbitrary header to all outgoing requests.
+ #:
+ #: This option should prefix the name of the header to add
+ #: (i.e. it should be used like
+ #: ``f"{DatabaseOptions.RpcCallHeaderPrefix}.x-my-header"``).
+ RPC_CALL_HEADER_PREFIX = "adbc.flight.sql.rpc.call_header."
+ #: Set a timeout on calls that fetch data (in floating-point seconds).
+ #:
+ #: This corresponds to Flight RPC DoGet calls.
+ TIMEOUT_FETCH = "adbc.flight.sql.rpc.timeout_seconds.fetch"
+ #: Set a timeout on calls that execute queries (in floating-point
+ #: seconds).
+ #:
+ #: This corresponds to Flight RPC GetFlightInfo calls.
+ TIMEOUT_QUERY = "adbc.flight.sql.rpc.timeout_seconds.query"
+ #: Set a timeout on calls that upload or update data (in
+ #: floating-point seconds).
+ TIMEOUT_UPDATE = "adbc.flight.sql.rpc.timeout_seconds.update"
+ #: Override the hostname used for TLS.
+ TLS_OVERRIDE_HOSTNAME =
"adbc.flight.sql.client_option.tls_override_hostname"
+ #: Use these PEM-encoded root certificates for TLS.
+ TLS_ROOT_CERTS = "adbc.flight.sql.client_option.tls_root_certs"
+ #: Do not verify the server's TLS certificate.
+ TLS_SKIP_VERIFY = "adbc.flight.sql.client_option.tls_skip_verify"
+ #: Block and wait for the connection to be established.
+ WITH_BLOCK = "adbc.flight.sql.client_option.with_block"
+ #: Set the maximum gRPC message size (in bytes). The default is 16 MiB.
+ WITH_MAX_MSG_SIZE = "adbc.flight.sql.client_option.with_max_msg_size"
+
+
+class ConnectionOptions(enum.Enum):
+ """Connection options specific to the Flight SQL driver."""
+
+ #: Add an arbitrary header to all outgoing requests.
+ #:
+ #: This option should prefix the name of the header to add
+ #: (i.e. it should be used like
+ #: ``f"{ConnectionOptions.RpcCallHeaderPrefix}.x-my-header"``).
+ #:
+ #: Overrides any headers set via the equivalent database option.
+ RPC_CALL_HEADER_PREFIX = DatabaseOptions.RPC_CALL_HEADER_PREFIX.value
+ #: Set a timeout on calls that fetch data (in floating-point seconds).
+ #:
+ #: This corresponds to Flight RPC DoGet calls.
+ TIMEOUT_FETCH = DatabaseOptions.TIMEOUT_FETCH.value
+ #: Set a timeout on calls that execute queries (in floating-point
+ #: seconds).
+ #:
+ #: This corresponds to Flight RPC GetFlightInfo calls.
+ TIMEOUT_QUERY = DatabaseOptions.TIMEOUT_QUERY.value
+ #: Set a timeout on calls that upload or update data (in
+ #: floating-point seconds).
+ TIMEOUT_UPDATE = DatabaseOptions.TIMEOUT_UPDATE.value
+
+
+class StatementOptions(enum.Enum):
+ """Statement options specific to the Flight SQL driver."""
-__all__ = ["connect", "__version__"]
+ #: The number of batches to queue per partition. Defaults to 5.
+ #:
+ #: This controls how much we read ahead on result sets.
+ QUEUE_SIZE = "adbc.flight.sql.rpc.queue_size"
+ #: Add an arbitrary header to all outgoing requests.
+ #:
+ #: This option should prefix the name of the header to add
+ #: (i.e. it should be used like
+ #: ``f"{ConnectionOptions.RpcCallHeaderPrefix}.x-my-header"``).
+ #:
+ #: Overrides any headers set via the equivalent database or
+ #: connection options.
+ RPC_CALL_HEADER_PREFIX = DatabaseOptions.RPC_CALL_HEADER_PREFIX.value
+ #: Set the Substrait version passed in the Flight SQL request.
+ #:
+ #: Most servers will not make use of this since the Substrait
+ #: specification was updated to embed the version in the plan
+ #: itself after this was originally added to Flight SQL.
+ SUBSTRAIT_VERSION = "adbc.flight.sql.substrait.version"
+ #: Set a timeout on calls that fetch data (in floating-point seconds).
+ #:
+ #: This corresponds to Flight RPC DoGet calls.
+ TIMEOUT_FETCH = DatabaseOptions.TIMEOUT_FETCH.value
+ #: Set a timeout on calls that execute queries (in floating-point
+ #: seconds).
+ #:
+ #: This corresponds to Flight RPC GetFlightInfo calls.
+ TIMEOUT_QUERY = DatabaseOptions.TIMEOUT_QUERY.value
+ #: Set a timeout on calls that upload or update data (in
+ #: floating-point seconds).
+ TIMEOUT_UPDATE = DatabaseOptions.TIMEOUT_UPDATE.value
def connect(
diff --git a/python/adbc_driver_flightsql/tests/conftest.py
b/python/adbc_driver_flightsql/tests/conftest.py
index 175c226..b80f952 100644
--- a/python/adbc_driver_flightsql/tests/conftest.py
+++ b/python/adbc_driver_flightsql/tests/conftest.py
@@ -39,8 +39,8 @@ def dremio(dremio_uri):
with adbc_driver_flightsql.connect(
dremio_uri,
db_kwargs={
- "username": username,
- "password": password,
+ adbc_driver_manager.DatabaseOptions.USERNAME.value: username,
+ adbc_driver_manager.DatabaseOptions.PASSWORD.value: password,
},
) as db:
with adbc_driver_manager.AdbcConnection(db) as conn:
@@ -54,8 +54,8 @@ def dremio_dbapi(dremio_uri):
with adbc_driver_flightsql.dbapi.connect(
dremio_uri,
db_kwargs={
- "username": username,
- "password": password,
+ adbc_driver_manager.DatabaseOptions.USERNAME.value: username,
+ adbc_driver_manager.DatabaseOptions.PASSWORD.value: password,
},
) as conn:
yield conn
diff --git a/python/adbc_driver_flightsql/tests/test_lowlevel.py
b/python/adbc_driver_flightsql/tests/test_lowlevel.py
index 7e1c00e..203b95b 100644
--- a/python/adbc_driver_flightsql/tests/test_lowlevel.py
+++ b/python/adbc_driver_flightsql/tests/test_lowlevel.py
@@ -29,5 +29,19 @@ def test_query_trivial(dremio):
assert reader.read_all()
+def test_options(dremio):
+ with adbc_driver_manager.AdbcStatement(dremio) as stmt:
+ stmt.set_options(
+ **{
+ adbc_driver_flightsql.StatementOptions.QUEUE_SIZE.value: "2",
+ adbc_driver_flightsql.StatementOptions.TIMEOUT_FETCH.value:
"10",
+ }
+ )
+ stmt.set_sql_query("SELECT 1")
+ stream, _ = stmt.execute_query()
+ reader = pyarrow.RecordBatchReader._import_from_c(stream.address)
+ assert reader.read_all()
+
+
def test_version():
assert adbc_driver_flightsql.__version__
diff --git a/python/adbc_driver_manager/adbc_driver_manager/__init__.py
b/python/adbc_driver_manager/adbc_driver_manager/__init__.py
index 2d91d82..e2eaee5 100644
--- a/python/adbc_driver_manager/adbc_driver_manager/__init__.py
+++ b/python/adbc_driver_manager/adbc_driver_manager/__init__.py
@@ -22,6 +22,8 @@ definitions in Python. For a higher-level interface, use
:mod:`adbc_driver_manager.dbapi`. (This requires PyArrow.)
"""
+import enum
+
from ._lib import (
INGEST_OPTION_MODE,
INGEST_OPTION_MODE_APPEND,
@@ -47,10 +49,9 @@ from ._lib import (
ProgrammingError,
Warning,
)
-from ._version import __version__
+from ._version import __version__ # noqa:F401
__all__ = [
- "__version__",
"INGEST_OPTION_MODE",
"INGEST_OPTION_MODE_APPEND",
"INGEST_OPTION_MODE_CREATE",
@@ -63,7 +64,9 @@ __all__ = [
"ArrowArrayHandle",
"ArrowArrayStreamHandle",
"ArrowSchemaHandle",
+ "ConnectionOptions",
"DatabaseError",
+ "DatabaseOptions",
"DataError",
"Error",
"GetObjectsDepth",
@@ -73,5 +76,41 @@ __all__ = [
"NotSupportedError",
"OperationalError",
"ProgrammingError",
+ "StatementOptions",
"Warning",
]
+
+
+class DatabaseOptions(enum.Enum):
+ """
+ Database options that are standardized between drivers.
+
+ Not all drivers support all options.
+ """
+
+ #: Set the password to use for username-password authentication.
+ PASSWORD = "password"
+ #: Set the username to use for username-password authentication.
+ USERNAME = "username"
+
+
+class ConnectionOptions(enum.Enum):
+ """Connection options that are standardized between drivers.
+
+ Not all drivers support all options.
+ """
+
+ #: Set the transaction isolation level.
+ ISOLATION_LEVEL = "adbc.connection.transaction.isolation_level"
+
+
+class StatementOptions(enum.Enum):
+ """Statement options that are standardized between drivers.
+
+ Not all drivers support all options.
+ """
+
+ #: For bulk ingestion, whether to create or append to the table.
+ INGEST_MODE = INGEST_OPTION_MODE
+ #: For bulk ingestion, the table to ingest into.
+ INGEST_TARGET_TABLE = INGEST_OPTION_TARGET_TABLE
diff --git a/python/adbc_driver_manager/adbc_driver_manager/_lib.pyx
b/python/adbc_driver_manager/adbc_driver_manager/_lib.pyx
index fac37e8..63c965d 100644
--- a/python/adbc_driver_manager/adbc_driver_manager/_lib.pyx
+++ b/python/adbc_driver_manager/adbc_driver_manager/_lib.pyx
@@ -567,6 +567,11 @@ cdef class AdbcDatabase(_AdbcHandle):
"""Set arbitrary key-value options.
Note, not all drivers support setting options after creation.
+
+ See Also
+ --------
+ adbc_driver_manager.DatabaseOptions : Standard option names.
+
"""
cdef CAdbcError c_error = empty_error()
cdef char* c_key = NULL
@@ -817,6 +822,10 @@ cdef class AdbcConnection(_AdbcHandle):
"""Set arbitrary key-value options.
Note, not all drivers support setting options after creation.
+
+ See Also
+ --------
+ adbc_driver_manager.ConnectionOptions : Standard option names.
"""
cdef CAdbcError c_error = empty_error()
cdef char* c_key = NULL
@@ -1045,7 +1054,12 @@ cdef class AdbcStatement(_AdbcHandle):
check_error(status, &c_error)
def set_options(self, **kwargs) -> None:
- """Set arbitrary key-value options."""
+ """Set arbitrary key-value options.
+
+ See Also
+ --------
+ adbc_driver_manager.StatementOptions : Standard option names.
+ """
cdef CAdbcError c_error = empty_error()
cdef char* c_key = NULL
cdef char* c_value = NULL
diff --git a/python/adbc_driver_sqlite/adbc_driver_sqlite/__init__.py
b/python/adbc_driver_sqlite/adbc_driver_sqlite/__init__.py
index 5422ff3..c8173f4 100644
--- a/python/adbc_driver_sqlite/adbc_driver_sqlite/__init__.py
+++ b/python/adbc_driver_sqlite/adbc_driver_sqlite/__init__.py
@@ -15,14 +15,24 @@
# specific language governing permissions and limitations
# under the License.
+"""Low-level ADBC bindings for the SQLite driver."""
+
+import enum
import functools
import typing
import adbc_driver_manager
-from ._version import __version__
+from ._version import __version__ # noqa:F401
+
+__all__ = ["StatementOptions", "connect"]
+
+
+class StatementOptions(enum.Enum):
+ """Statement options specific to the SQLite driver."""
-__all__ = ["connect", "__version__"]
+ #: The number of rows per batch. Defaults to 1024.
+ BATCH_ROWS = "adbc.sqlite.query.batch_rows"
def connect(uri: typing.Optional[str] = None) ->
adbc_driver_manager.AdbcDatabase:
diff --git a/python/adbc_driver_sqlite/tests/test_lowlevel.py
b/python/adbc_driver_sqlite/tests/test_lowlevel.py
index fd83933..6ab0acb 100644
--- a/python/adbc_driver_sqlite/tests/test_lowlevel.py
+++ b/python/adbc_driver_sqlite/tests/test_lowlevel.py
@@ -37,5 +37,18 @@ def test_query_trivial(sqlite):
assert reader.read_all()
+def test_options(sqlite):
+ with adbc_driver_manager.AdbcStatement(sqlite) as stmt:
+ stmt.set_options(
+ **{
+ adbc_driver_sqlite.StatementOptions.BATCH_ROWS.value: "1",
+ }
+ )
+ stmt.set_sql_query("SELECT 1")
+ stream, _ = stmt.execute_query()
+ reader = pyarrow.RecordBatchReader._import_from_c(stream.address)
+ assert reader.read_all()
+
+
def test_version():
assert adbc_driver_sqlite.__version__