Skip to main content

A Python DBAPI 2.0 client for Tencent Cloud DLC (Data Lake Compute) via HiveServer2 Thrift

Project description

dlc-sql-python

A Python DBAPI 2.0 (PEP 249) client for Tencent Cloud DLC (Data Lake Compute), connecting to its HiveServer2-compatible Thrift endpoint (TCLIService).

It is the connection layer used by dbt-dlc (a dbt adapter that extends dbt-spark), and is the Python counterpart of the TypeScript dlc-sql-nodejs reference implementation.

Features

  • DBAPI 2.0 compliantapilevel='2.0', paramstyle='pyformat', full connect / cursor / execute / fetchone / fetchmany / fetchall / description / rowcount API and PEP 249 exception hierarchy.
  • Three transport modes
    • binary (default) — TCP socket + custom SASL PLAIN handshake + framed TBinaryProtocol.
    • http — HTTP POST with X-DLC-* auth headers.
    • https — HTTPS POST with X-DLC-* auth headers (production / public endpoints).
  • Two authentication modes
    • AccessKey — Tencent Cloud SecretId / SecretKey.
    • RoleBasedSSO — role-based SSO with a pre-obtained access token (Manual), plus an OAuthManager helper for M2M (client_credentials) and U2M (authorization_code + PKCE, browser login) token acquisition.
  • Async execution + pollingExecuteStatement(runAsync=true) → poll GetOperationStatusGetResultSetMetadataFetchResults.
  • Columnar result parsingTColumn union (bool/byte/i16/i32/i64/double/ string/binary) + nulls bitmap → Python values.

Installation

pip install dlc-sql-python

From source (development):

cd dlc-sql-python
pip install -e ".[dev]"
pytest

Quick start

import dlc_sql

conn = dlc_sql.connect(
    host="dlc-thrift.example.com",
    engine_name="my-spark-engine",
    resource_group_name="my-resource-group",
    catalog="hive",
    database="default",
    auth_mode="AccessKey",
    transport_mode="https",      # or "binary" / "http"
    port=443,
    secret_id="AKIDxxxx",        # via env var in production
    secret_key="xxxx",
)
cursor = conn.cursor()
cursor.execute("SELECT id, name FROM users WHERE id = %(id)s", {"id": 1})
print(cursor.description)
print(cursor.fetchall())
cursor.close()
conn.close()

Connection parameters

Parameter Required Default Description
host yes DLC Thrift endpoint host
engine_name yes Spark engine name
resource_group_name yes Resource group name
catalog yes Catalog (e.g. hive)
database yes Database (schema is accepted as an alias)
auth_mode yes AccessKey or RoleBasedSSO
transport_mode no binary binary / http / https
port no 10009 (binary/http), 443 (https) Thrift port
http_path no /cliservice HTTP path (http/https)
socket_timeout_ms no 60000 Transport timeout
secret_id / secret_key AccessKey Tencent Cloud AK/SK
role_arn / identity_provider_name / access_token RoleBasedSSO SSO role + token (Manual)
query_timeout_seconds no 0 (unlimited) Server-side query timeout
poll_interval_ms no 500 Status polling interval
max_rows no 10000 Rows per FetchResults batch
start_session_props no {} Extra OpenSession configuration
use_arrow_result / arrow_batch_size no False / 10000 Kyuubi Arrow result format (enhancement)

Security: never hard-code credentials. Pass secret_id / secret_key / access_token via environment variables. HTTPS mode verifies server certificates with the system CA store.

Authentication

AccessKey (binary)

The SASL username encodes engine&rg&AKSK[&catalog[&database]] (AKSK is the wire tag for the AccessKey auth mode) and the password encodes secretId&secretKey; the SDK assembles these automatically.

RoleBasedSSO

Pass a pre-obtained access_token, or resolve one with OAuthManager:

from dlc_sql.auth import OAuthManager, RoleBasedSSOAuth

# M2M (client_credentials) — CI/CD
mgr = OAuthManager(
    token_url="https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token",
    client_id="<client_id>",
    client_secret="<client_secret>",
    scopes=["api://dlc/.default"],
)
token = mgr.get_access_token()

# U2M (authorization_code + PKCE, browser) — local dev
mgr = OAuthManager(
    token_url="https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token",
    authorize_url="https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize",
    client_id="<client_id>",
    scopes=["api://dlc/.default", "offline_access"],
    callback_port=8030,
    persistence_path="~/.dlc/token_cache.json",
)
token = mgr.get_access_token()

Then connect with auth_mode="RoleBasedSSO", role_arn=..., identity_provider_name=..., access_token=token.

Architecture

dlc_sql.connect(...)
   └── Connection ── open_session ──┐
         └── Cursor ── execute / fetch
               │
   ┌───────────┴───────────────┐
   │  ThriftTransport          │  binary | http | https
   │   └ send_request(bytes)   │
   └───────────┬───────────────┘
               │
   thrift_api/codec.create_client(transport)
        → TCLIService.Client over TBinaryProtocol
               │
   dlc_sql/thrift_api/TCLIService/   (vendored from PyHive)

The codec bridges our custom ThriftTransport (which carries raw TBinaryProtocol request/response bytes — handling the custom SASL PLAIN handshake and framing, or HTTP POST) onto a Thrift TTransport so the vendored TCLIService.Client drives the RPCs directly. This avoids the thrift_sasl dependency (DLC's SASL is a custom variant) while keeping the full Thrift message envelope correct.

Module layout

dlc_sql/
├── __init__.py          # DBAPI 2.0 entry point (apilevel, connect, exceptions)
├── connection.py        # Connection + connect()
├── cursor.py            # Cursor (execute / poll / fetch)
├── session.py           # OpenSession/CloseSession + config assembly
├── exceptions.py        # PEP 249 + DLC-specific exceptions
├── types.py             # options, type map, columnar result + schema parsing
├── auth/
│   ├── base.py          # AuthProvider ABC
│   ├── access_key.py    # AccessKeyAuth (AK/SK)
│   ├── role_sso.py      # RoleBasedSSOAuth (Manual token)
│   ├── oauth.py         # OAuthManager (M2M + U2M/PKCE)
│   └── __init__.py      # factory + assemble_sasl_credentials
├── transport/
│   ├── base.py          # ThriftTransport ABC
│   ├── binary.py        # BinaryTransport (SASL + framed)
│   ├── http.py          # HttpTransport (HTTP/HTTPS + X-DLC-* headers)
│   ├── factory.py       # create_transport()
│   └── __init__.py
└── thrift_api/
    ├── codec.py         # TTransport adapter → TCLIService.Client
    └── TCLIService/     # vendored from PyHive (HiveServer2 IDL)

DBAPI 2.0 conformance

  • apilevel = "2.0", paramstyle = "pyformat", threadsafety = 1.
  • Connection: cursor(), commit() / rollback() (no-ops, DLC has no transactions), close(), context-manager support.
  • Cursor: execute(), executemany(), fetchone(), fetchmany(), fetchall(), cancel(), close(), description, rowcount (-1, DLC does not report affected rows), arraysize, context-manager support.
  • Exceptions: Error, Warning, InterfaceError, DatabaseError, InternalError, OperationalError, ProgrammingError, IntegrityError, DataError, NotSupportedError (+ DlcSqlConnectionError, DlcSqlAuthError, DlcSqlOperationError subclasses).

Relationship to dbt-dlc

dbt-dlc extends dbt-spark, reusing all Spark SQL macros and overriding only the connection layer to use dlc-sql-python. See the companion spec in docs/specs/ for the dbt-dlc design.

License

Apache License 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dlc_sql_python-1.0.1.tar.gz (57.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dlc_sql_python-1.0.1-py3-none-any.whl (55.9 kB view details)

Uploaded Python 3

File details

Details for the file dlc_sql_python-1.0.1.tar.gz.

File metadata

  • Download URL: dlc_sql_python-1.0.1.tar.gz
  • Upload date:
  • Size: 57.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.7.4

File hashes

Hashes for dlc_sql_python-1.0.1.tar.gz
Algorithm Hash digest
SHA256 8ced1f72b1abec92ba6419e9bd0271b8cd3830d89e0f392756a4a245403654ce
MD5 501dc18b74740ba7ceb7cc0e1aaa1dce
BLAKE2b-256 33c973b6e928028b28d696019f02d37f9a4f57d538aba43f767d51de34cfae5d

See more details on using hashes here.

File details

Details for the file dlc_sql_python-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: dlc_sql_python-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 55.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.7.4

File hashes

Hashes for dlc_sql_python-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0dbae519088a46dbf5a028757983f51152f0899b7a22121a51c0bf177a90964f
MD5 7f7f2e75aefa4143afdd333e794df008
BLAKE2b-256 51e2a145892d3d76721bc592c6439f2c7718b0216e7d646e4da91a5049be0e81

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page