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__

Reply via email to