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 compliant —
apilevel='2.0',paramstyle='pyformat', fullconnect/cursor/execute/fetchone/fetchmany/fetchall/description/rowcountAPI and PEP 249 exception hierarchy. - Three transport modes
binary(default) — TCP socket + custom SASL PLAIN handshake + framedTBinaryProtocol.http— HTTP POST withX-DLC-*auth headers.https— HTTPS POST withX-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 anOAuthManagerhelper for M2M (client_credentials) and U2M (authorization_code + PKCE, browser login) token acquisition.
- Async execution + polling —
ExecuteStatement(runAsync=true)→ pollGetOperationStatus→GetResultSetMetadata→FetchResults. - Columnar result parsing —
TColumnunion (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_tokenvia 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,DlcSqlOperationErrorsubclasses).
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ced1f72b1abec92ba6419e9bd0271b8cd3830d89e0f392756a4a245403654ce
|
|
| MD5 |
501dc18b74740ba7ceb7cc0e1aaa1dce
|
|
| BLAKE2b-256 |
33c973b6e928028b28d696019f02d37f9a4f57d538aba43f767d51de34cfae5d
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dbae519088a46dbf5a028757983f51152f0899b7a22121a51c0bf177a90964f
|
|
| MD5 |
7f7f2e75aefa4143afdd333e794df008
|
|
| BLAKE2b-256 |
51e2a145892d3d76721bc592c6439f2c7718b0216e7d646e4da91a5049be0e81
|