confluent-sql 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/ARCHITECTURE.md +6 -6
- confluent_sql-0.3.0/CHANGELOG.md +37 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/DBAPI_EXTENSIONS.md +51 -16
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/PKG-INFO +41 -12
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/README.md +40 -11
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/STREAMING.md +1 -1
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/examples/errors.py +1 -1
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/examples/simple_append_only_streaming_query_example.py +1 -1
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/examples/snapshot_mode_tuple_cursor_simple_example.py +1 -1
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/pyproject.toml +1 -1
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/__init__.py +4 -1
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/connection.py +197 -56
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/cursor.py +29 -12
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/exceptions.py +40 -1
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/statement.py +4 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/conftest.py +4 -4
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/integration/conftest.py +87 -5
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/integration/test_connection.py +61 -1
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/integration/test_cursor.py +68 -2
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_connection_unit.py +493 -36
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_connection_unit_properties.py +1 -1
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_cursor_unit.py +83 -0
- confluent_sql-0.3.0/uv.lock +439 -0
- confluent_sql-0.2.0/CHANGELOG.md +0 -24
- confluent_sql-0.2.0/uv.lock +0 -439
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.github/CODEOWNERS +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.gitignore +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.semaphore/publish_to_codeartifact.yml +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.semaphore/publish_to_pypi.yml +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.semaphore/semaphore.yml +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/LICENSE.txt +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/Makefile +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/TYPES.md +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/service.yml +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/__version__.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/changelog_compressor.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/execution_mode.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/result_readers.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/types.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/__init__.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/integration/test_fetch.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/conftest.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_changelog_compressor_unit.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_changelog_unit.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_execution_mode_unit.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_result_readers_unit.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_statement_unit.py +0 -0
- {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_types_unit.py +0 -0
|
@@ -143,20 +143,20 @@ cursor2.execute("SELECT * FROM table2", statement_name="my-query") # ❌ Error:
|
|
|
143
143
|
In addition to individual statement names, you can use statement labels to group related statements together for batch operations:
|
|
144
144
|
|
|
145
145
|
```python
|
|
146
|
-
# Group multiple statements with
|
|
146
|
+
# Group multiple statements with labels
|
|
147
147
|
cursor1 = connection.cursor()
|
|
148
148
|
cursor1.execute(
|
|
149
149
|
"SELECT COUNT(*) FROM events",
|
|
150
|
-
|
|
150
|
+
statement_labels=["hourly-metrics", "analytics"]
|
|
151
151
|
)
|
|
152
152
|
|
|
153
153
|
cursor2 = connection.cursor()
|
|
154
154
|
cursor2.execute(
|
|
155
155
|
"SELECT * FROM users",
|
|
156
|
-
|
|
156
|
+
statement_labels=["hourly-metrics", "analytics"]
|
|
157
157
|
)
|
|
158
158
|
|
|
159
|
-
# Later, find all statements with
|
|
159
|
+
# Later, find all statements with any of the labels to then delete
|
|
160
160
|
statements = connection.list_statements(label="hourly-metrics")
|
|
161
161
|
for stmt in statements:
|
|
162
162
|
print(f"{stmt.name}: {stmt.phase}")
|
|
@@ -175,8 +175,8 @@ Statements persist on the server independently of your client connection, but ar
|
|
|
175
175
|
statement = connection.execute_snapshot_ddl(
|
|
176
176
|
"CREATE TABLE daily_summary AS SELECT * FROM events WHERE date > %s",
|
|
177
177
|
(start_date,),
|
|
178
|
-
statement_name="daily-summary-job"
|
|
179
|
-
|
|
178
|
+
statement_name="daily-summary-job",
|
|
179
|
+
statement_labels=["daily-jobs", "etl"]
|
|
180
180
|
)
|
|
181
181
|
```
|
|
182
182
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this dbapi driver will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## 0.3.0, 2026-04-09
|
|
6
|
+
|
|
7
|
+
### Changed - Breaking
|
|
8
|
+
* `connect()` / `Connection.__init__()`: Renamed `environment` parameter to `environment_id` to clarify that an environment ID (_not_ name) is expected. The internal attribute `Connection.environment` has also been renamed to `Connection.environment_id`. Update all calls from `connect(environment="env-123")` to `connect(environment_id="env-123")`. (#92)
|
|
9
|
+
* `Cursor.execute()` and peers: Respelled and re-typed the `statement_label: str | None` parameter to be `statement_labels: list[str] | None` to allow multiple labels to be applied to a statement, including `HIDDEN_LABEL`.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
* New `Connection.get_statement(statement)` method to retrieve statement metadata by name or refresh a Statement object with the latest server state. Accepts either a statement name (string) or a Statement object. Returns a Statement object with current phase, schema, and execution traits. (#86)
|
|
13
|
+
* New `StatementNotFoundError` exception, a subclass of `OperationalError`, raised by `Connection.get_statement(statement)` when attempting to retrieve a statement that does not exist. Provides programmatic access to the statement name via the `statement_name` attribute.
|
|
14
|
+
* New constant `confluent_sql.HIDDEN_LABEL` used for driving `Cursor.execute()` to indicate that the statement should be hidden in default listings in Confluent Cloud UIs. This feature is intended to be used for minor queries, such as when investigating `INFORMATION_SCHEMA`.
|
|
15
|
+
* Added documentation regarding use of `connect(endpoint=)` parameter to make use of private networking endpoints (README.md, docstrings).
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## 0.2.0, 2026-03-26
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
* Respelled the `connect()` parameter `dbname` to `database`. The old spelling `dbname` is deprecated and will be removed in after one release cycle.
|
|
23
|
+
* Class `SqlNone` now gracefully strips trailing `NOT NULL` constraints from type names (case-insensitively), so that `str(SqlNone("DATE NOT NULL"))` returns valid FlinkSQL `"cast (null as DATE)"`.
|
|
24
|
+
* `connect()` is now keyword-only callable.
|
|
25
|
+
* The `host` parameter for `Connection.__init__()` has been renamed to `endpoint`.
|
|
26
|
+
* Clarified and improved documentation around Flink region API key use.
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
* New optional keyword parameter `properties: PropertiesDict | None` on `Cursor.execute()` and related methods to allow callers to provide [statement execution properties](https://docs.confluent.io/cloud/current/flink/reference/statements/set.html#table-options). Note: connection or cursor-level properties for default catalog, database, and execution mode cannot be overridden by this parameter.
|
|
30
|
+
* New optional `endpoint` parameter on `connect()` and `Connection.__init__` to allow users to specify a custom Confluent Cloud API base endpoint (e.g., for private networking, staging, etc.). Mutually exclusive with (`cloud_provider`, `cloud_region`) -- either `endpoint` or (`cloud_provider`, `cloud_region`) must be provided. This replaces the `host` parameter in `Connection.__init__()`. (#66)
|
|
31
|
+
|
|
32
|
+
### Removed
|
|
33
|
+
* The unused control-plane `api_key` and `api_secret` `connect()` parameters have been removed. The Flink Region API key params `flink_api_key` and `flink_api_secret` remain.
|
|
34
|
+
|
|
35
|
+
## 0.1.x
|
|
36
|
+
|
|
37
|
+
Early access release of the driver.
|
|
@@ -386,7 +386,7 @@ Use for statements that produce unbounded/continuous results:
|
|
|
386
386
|
Both `execute_snapshot_ddl()` and `execute_streaming_ddl()` also accept these parameters for controlling statement identity and lifecycle:
|
|
387
387
|
|
|
388
388
|
- `statement_name` (str | None): Custom statement identifier (defaults to auto-generated UUID)
|
|
389
|
-
- `
|
|
389
|
+
- `statement_labels` (list[str] | None): List of labels for grouping related statements
|
|
390
390
|
|
|
391
391
|
Example with statement naming and labeling:
|
|
392
392
|
|
|
@@ -394,10 +394,10 @@ Example with statement naming and labeling:
|
|
|
394
394
|
statement = connection.execute_streaming_ddl(
|
|
395
395
|
"CREATE TABLE orders_stream AS SELECT * FROM kafka_orders",
|
|
396
396
|
statement_name="orders-stream-job",
|
|
397
|
-
|
|
397
|
+
statement_labels=["data-pipelines", "streaming"]
|
|
398
398
|
)
|
|
399
399
|
|
|
400
|
-
# Later, find all statements with
|
|
400
|
+
# Later, find all statements with any of the labels
|
|
401
401
|
statements = connection.list_statements(label="data-pipelines")
|
|
402
402
|
```
|
|
403
403
|
|
|
@@ -424,13 +424,21 @@ connection.delete_statement("active-users-query")
|
|
|
424
424
|
**Statement Labels** - Group related statements for batch operations
|
|
425
425
|
|
|
426
426
|
```python
|
|
427
|
-
|
|
427
|
+
from confluent_sql import HIDDEN_LABEL
|
|
428
|
+
|
|
429
|
+
# Execute multiple statements with labels
|
|
428
430
|
for source in ["kafka_topic_a", "kafka_topic_b", "kafka_topic_c"]:
|
|
429
431
|
cursor.execute(
|
|
430
432
|
f"CREATE TABLE {source}_backup AS SELECT * FROM {source}",
|
|
431
|
-
|
|
433
|
+
statement_labels=["daily-backups", "batch-job"]
|
|
432
434
|
)
|
|
433
435
|
|
|
436
|
+
# Mark a background job as hidden
|
|
437
|
+
cursor.execute(
|
|
438
|
+
"SELECT * FROM `INFORMATION_SCHEMA`.`TABLES`",
|
|
439
|
+
statement_labels=[HIDDEN_LABEL]
|
|
440
|
+
)
|
|
441
|
+
|
|
434
442
|
# Later, list and delete all backups
|
|
435
443
|
statements = connection.list_statements(label="daily-backups")
|
|
436
444
|
for stmt in statements:
|
|
@@ -459,6 +467,33 @@ for statement in statements:
|
|
|
459
467
|
print(f"Created: {statement.created_at}")
|
|
460
468
|
```
|
|
461
469
|
|
|
470
|
+
**`get_statement()` - Retrieve statement by exact name**
|
|
471
|
+
|
|
472
|
+
```python
|
|
473
|
+
# Get statement by name
|
|
474
|
+
stmt = connection.get_statement("my-statement-name")
|
|
475
|
+
print(f"Status: {stmt.phase}") # PENDING, RUNNING, COMPLETED, FAILED, etc.
|
|
476
|
+
|
|
477
|
+
# Check if results are ready
|
|
478
|
+
if stmt.can_fetch_results(ExecutionMode.SNAPSHOT):
|
|
479
|
+
# Results are available
|
|
480
|
+
...
|
|
481
|
+
|
|
482
|
+
# Refresh a Statement object with latest server state
|
|
483
|
+
stmt = cursor.statement
|
|
484
|
+
time.sleep(5)
|
|
485
|
+
stmt = connection.get_statement(stmt) # Fetch updated state
|
|
486
|
+
print(f"Updated phase: {stmt.phase}")
|
|
487
|
+
|
|
488
|
+
# Raises StatementNotFoundError if statement not found
|
|
489
|
+
try:
|
|
490
|
+
stmt = connection.get_statement("non-existent-statement")
|
|
491
|
+
except StatementNotFoundError as e:
|
|
492
|
+
print(f"Statement '{e.statement_name}' does not exist")
|
|
493
|
+
except OperationalError as e:
|
|
494
|
+
print(f"Other error: {e}")
|
|
495
|
+
```
|
|
496
|
+
|
|
462
497
|
**`delete_statement()` - Stop and remove a statement**
|
|
463
498
|
|
|
464
499
|
```python
|
|
@@ -807,21 +842,21 @@ cursor.execute(
|
|
|
807
842
|
*,
|
|
808
843
|
timeout: int = 3000,
|
|
809
844
|
statement_name: str | None = None,
|
|
810
|
-
|
|
845
|
+
statement_labels: list[str] | None = None,
|
|
811
846
|
properties: dict[str, str | int | bool] | None = None,
|
|
812
847
|
) -> None
|
|
813
848
|
```
|
|
814
849
|
|
|
815
850
|
### Parameter Reference
|
|
816
851
|
|
|
817
|
-
| Parameter
|
|
818
|
-
|
|
|
819
|
-
| `statement_text`
|
|
820
|
-
| `parameters`
|
|
821
|
-
| `timeout`
|
|
822
|
-
| `statement_name`
|
|
823
|
-
| `
|
|
824
|
-
| `properties`
|
|
852
|
+
| Parameter | Type | Default | Description |
|
|
853
|
+
| ------------------ | --------------------------------- | ---------- | ------------------------------------------------------------------ |
|
|
854
|
+
| `statement_text` | `str` | (required) | SQL statement to execute |
|
|
855
|
+
| `parameters` | `tuple \| list \| None` | None | Parameter values for parameterized statements |
|
|
856
|
+
| `timeout` | `int` | 3000 | Max seconds to wait for statement to reach RUNNING/COMPLETED phase |
|
|
857
|
+
| `statement_name` | `str \| None` | None | Custom statement identifier (defaults to UUID) |
|
|
858
|
+
| `statement_labels` | `list[str] \| None` | None | List of labels for grouping related statements |
|
|
859
|
+
| `properties` | `dict[str, str \| int \| bool] \| None` | None | [Statement properties](#statement-properties) to set for execution |
|
|
825
860
|
|
|
826
861
|
### Statement Properties
|
|
827
862
|
|
|
@@ -867,7 +902,7 @@ cursor.execute(
|
|
|
867
902
|
# With statement labeling (for batch operations)
|
|
868
903
|
cursor.execute(
|
|
869
904
|
"CREATE TABLE orders_backup AS SELECT * FROM orders",
|
|
870
|
-
|
|
905
|
+
statement_labels=["daily-backups", "batch-job"]
|
|
871
906
|
)
|
|
872
907
|
|
|
873
908
|
# All together
|
|
@@ -876,7 +911,7 @@ cursor.execute(
|
|
|
876
911
|
(),
|
|
877
912
|
timeout=3000,
|
|
878
913
|
statement_name="product-sales-hourly",
|
|
879
|
-
|
|
914
|
+
statement_labels=["analytics", "hourly"]
|
|
880
915
|
)
|
|
881
916
|
|
|
882
917
|
# With statement properties
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: confluent-sql
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: DB-API v2 compliant driver for Confluent Cloud Flink SQL
|
|
5
5
|
Project-URL: Repository, https://github.com/confluentinc/confluent-sql
|
|
6
6
|
Project-URL: Documentation, https://github.com/confluentinc/confluent-sql?tab=readme-ov-file#confluent-sql
|
|
@@ -251,8 +251,27 @@ The behavior of snapshot-mode cursors, complying with dbapi semantics, are well
|
|
|
251
251
|
|
|
252
252
|
- **Confluent Cloud account** with Flink environment
|
|
253
253
|
- **Active Flink compute pool** (must be pre-created)
|
|
254
|
-
- **Flink
|
|
254
|
+
- **Existing Flink Database** (Confluent Cloud Kafka cluster)
|
|
255
|
+
- **Flink Region API credentials** for Flink SQL Region API access: a user or service account Flink region API key and secret.
|
|
255
256
|
|
|
257
|
+
### How to Obtain a Flink Region API Key
|
|
258
|
+
|
|
259
|
+
This driver requires a **Flink Region API key** (also called a Flink SQL API key), which is specific to your Flink compute pool and provides access to the regional Flink SQL API endpoints. This is distinct from a Confluent Cloud control-plane API key.
|
|
260
|
+
|
|
261
|
+
To create or find a Flink Region API key:
|
|
262
|
+
|
|
263
|
+
1. Go to [https://confluent.cloud/settings/api-keys](https://confluent.cloud/settings/api-keys)
|
|
264
|
+
2. Filter by resource **'Flink Region'**
|
|
265
|
+
3. Find an existing key, or follow the **'+ Add API Key'** path to create a new one
|
|
266
|
+
4. When creating a new key, select either:
|
|
267
|
+
- **My account** - for development/testing
|
|
268
|
+
- **Service account** - for production applications (recommended)
|
|
269
|
+
and then:
|
|
270
|
+
- **The Environment, Cloud Provider and Cloud Region** matching the Flink database(s) / Kafka cluster(s) you intend to use this driver against.
|
|
271
|
+
5. Save both the **API key** and **API secret** securely (the secret cannot be retrieved later)
|
|
272
|
+
6. Use these credentials as the `flink_api_key` and `flink_api_secret` parameters in the `connect()` function
|
|
273
|
+
|
|
274
|
+
API keys may also be generated using the Confluent CLI or by API access, outside the scope of this document.
|
|
256
275
|
## Installation
|
|
257
276
|
|
|
258
277
|
```bash
|
|
@@ -272,14 +291,14 @@ import confluent_sql
|
|
|
272
291
|
|
|
273
292
|
# Connect to Confluent Cloud Flink SQL
|
|
274
293
|
connection = confluent_sql.connect(
|
|
275
|
-
flink_api_key="your-flink-api-key",
|
|
276
|
-
flink_api_secret="your-flink-api-secret",
|
|
277
294
|
organization_id="your-org-uuid",
|
|
278
|
-
|
|
279
|
-
compute_pool_id="lfcp-789012",
|
|
295
|
+
environment_id="env-123456",
|
|
280
296
|
cloud_provider="aws",
|
|
281
297
|
cloud_region="us-east-2",
|
|
282
|
-
|
|
298
|
+
flink_api_key="your-flink-api-key",
|
|
299
|
+
flink_api_secret="your-flink-api-secret",
|
|
300
|
+
database="your-database-name",
|
|
301
|
+
compute_pool_id="lfcp-789012"
|
|
283
302
|
)
|
|
284
303
|
```
|
|
285
304
|
|
|
@@ -379,6 +398,16 @@ For detailed streaming query guidance, see **[STREAMING.md](https://github.com/c
|
|
|
379
398
|
|
|
380
399
|
For type support and examples, see **[TYPES.md](https://github.com/confluentinc/confluent-sql/blob/main/TYPES.md)**.
|
|
381
400
|
|
|
401
|
+
|
|
402
|
+
## Private Networking Considerations
|
|
403
|
+
|
|
404
|
+
By default, this driver uses the public Confluent Cloud API networking endpoint for the provided cloud provider and region. However, if the Flink database / Kafka cluster you intend to query requires private networking connectivity, then provide the appropriate Flink private networking base URL as the `endpoint` parameter
|
|
405
|
+
to `connect()` or `Connection.__init__()`. Refer to the Confluent Cloud [Flink private networking documentation](https://docs.confluent.io/cloud/current/flink/concepts/flink-private-networking.html) for more information on composing your endpoint URL.
|
|
406
|
+
|
|
407
|
+
Symptoms of using the public endpoint when private networking is required include:
|
|
408
|
+
* HTTP 429-related exceptions raised when submitting statements querying tables whose backing Kafka topics / clusters are configured for private networking only.
|
|
409
|
+
* Empty or surprisingly missing results when querying `INFORMATION_SCHEMA` or `SHOW TABLES`, due to silent filtering of private-networking-only tables/topics when querying the system catalog.
|
|
410
|
+
|
|
382
411
|
## Development
|
|
383
412
|
|
|
384
413
|
### Setup
|
|
@@ -404,14 +433,14 @@ Set required environment variables for integration tests.
|
|
|
404
433
|
If any of the variables is not set, integration tests will be skipped.
|
|
405
434
|
|
|
406
435
|
```bash
|
|
407
|
-
export CONFLUENT_FLINK_API_KEY="your-key"
|
|
408
|
-
export CONFLUENT_FLINK_API_SECRET="your-secret"
|
|
409
|
-
export CONFLUENT_ENV_ID="env-123456"
|
|
410
436
|
export CONFLUENT_ORG_ID="org-123456"
|
|
411
|
-
export
|
|
437
|
+
export CONFLUENT_ENV_ID="env-123456"
|
|
412
438
|
export CONFLUENT_CLOUD_PROVIDER="aws"
|
|
413
439
|
export CONFLUENT_CLOUD_REGION="us-east-2"
|
|
414
|
-
export
|
|
440
|
+
export CONFLUENT_FLINK_API_KEY="your-key" # Flink Region API key for the above cloud/region ...
|
|
441
|
+
export CONFLUENT_FLINK_API_SECRET="your-secret" # and associated secret.
|
|
442
|
+
export CONFLUENT_COMPUTE_POOL_ID="lfcp-789012" # A compute pool within the above cloud/region.
|
|
443
|
+
export CONFLUENT_TEST_DBNAME="test-db" # A database/kafka cluster name within the above cloud/region.
|
|
415
444
|
```
|
|
416
445
|
|
|
417
446
|
Run tests:
|
|
@@ -20,8 +20,27 @@ The behavior of snapshot-mode cursors, complying with dbapi semantics, are well
|
|
|
20
20
|
|
|
21
21
|
- **Confluent Cloud account** with Flink environment
|
|
22
22
|
- **Active Flink compute pool** (must be pre-created)
|
|
23
|
-
- **Flink
|
|
23
|
+
- **Existing Flink Database** (Confluent Cloud Kafka cluster)
|
|
24
|
+
- **Flink Region API credentials** for Flink SQL Region API access: a user or service account Flink region API key and secret.
|
|
24
25
|
|
|
26
|
+
### How to Obtain a Flink Region API Key
|
|
27
|
+
|
|
28
|
+
This driver requires a **Flink Region API key** (also called a Flink SQL API key), which is specific to your Flink compute pool and provides access to the regional Flink SQL API endpoints. This is distinct from a Confluent Cloud control-plane API key.
|
|
29
|
+
|
|
30
|
+
To create or find a Flink Region API key:
|
|
31
|
+
|
|
32
|
+
1. Go to [https://confluent.cloud/settings/api-keys](https://confluent.cloud/settings/api-keys)
|
|
33
|
+
2. Filter by resource **'Flink Region'**
|
|
34
|
+
3. Find an existing key, or follow the **'+ Add API Key'** path to create a new one
|
|
35
|
+
4. When creating a new key, select either:
|
|
36
|
+
- **My account** - for development/testing
|
|
37
|
+
- **Service account** - for production applications (recommended)
|
|
38
|
+
and then:
|
|
39
|
+
- **The Environment, Cloud Provider and Cloud Region** matching the Flink database(s) / Kafka cluster(s) you intend to use this driver against.
|
|
40
|
+
5. Save both the **API key** and **API secret** securely (the secret cannot be retrieved later)
|
|
41
|
+
6. Use these credentials as the `flink_api_key` and `flink_api_secret` parameters in the `connect()` function
|
|
42
|
+
|
|
43
|
+
API keys may also be generated using the Confluent CLI or by API access, outside the scope of this document.
|
|
25
44
|
## Installation
|
|
26
45
|
|
|
27
46
|
```bash
|
|
@@ -41,14 +60,14 @@ import confluent_sql
|
|
|
41
60
|
|
|
42
61
|
# Connect to Confluent Cloud Flink SQL
|
|
43
62
|
connection = confluent_sql.connect(
|
|
44
|
-
flink_api_key="your-flink-api-key",
|
|
45
|
-
flink_api_secret="your-flink-api-secret",
|
|
46
63
|
organization_id="your-org-uuid",
|
|
47
|
-
|
|
48
|
-
compute_pool_id="lfcp-789012",
|
|
64
|
+
environment_id="env-123456",
|
|
49
65
|
cloud_provider="aws",
|
|
50
66
|
cloud_region="us-east-2",
|
|
51
|
-
|
|
67
|
+
flink_api_key="your-flink-api-key",
|
|
68
|
+
flink_api_secret="your-flink-api-secret",
|
|
69
|
+
database="your-database-name",
|
|
70
|
+
compute_pool_id="lfcp-789012"
|
|
52
71
|
)
|
|
53
72
|
```
|
|
54
73
|
|
|
@@ -148,6 +167,16 @@ For detailed streaming query guidance, see **[STREAMING.md](https://github.com/c
|
|
|
148
167
|
|
|
149
168
|
For type support and examples, see **[TYPES.md](https://github.com/confluentinc/confluent-sql/blob/main/TYPES.md)**.
|
|
150
169
|
|
|
170
|
+
|
|
171
|
+
## Private Networking Considerations
|
|
172
|
+
|
|
173
|
+
By default, this driver uses the public Confluent Cloud API networking endpoint for the provided cloud provider and region. However, if the Flink database / Kafka cluster you intend to query requires private networking connectivity, then provide the appropriate Flink private networking base URL as the `endpoint` parameter
|
|
174
|
+
to `connect()` or `Connection.__init__()`. Refer to the Confluent Cloud [Flink private networking documentation](https://docs.confluent.io/cloud/current/flink/concepts/flink-private-networking.html) for more information on composing your endpoint URL.
|
|
175
|
+
|
|
176
|
+
Symptoms of using the public endpoint when private networking is required include:
|
|
177
|
+
* HTTP 429-related exceptions raised when submitting statements querying tables whose backing Kafka topics / clusters are configured for private networking only.
|
|
178
|
+
* Empty or surprisingly missing results when querying `INFORMATION_SCHEMA` or `SHOW TABLES`, due to silent filtering of private-networking-only tables/topics when querying the system catalog.
|
|
179
|
+
|
|
151
180
|
## Development
|
|
152
181
|
|
|
153
182
|
### Setup
|
|
@@ -173,14 +202,14 @@ Set required environment variables for integration tests.
|
|
|
173
202
|
If any of the variables is not set, integration tests will be skipped.
|
|
174
203
|
|
|
175
204
|
```bash
|
|
176
|
-
export CONFLUENT_FLINK_API_KEY="your-key"
|
|
177
|
-
export CONFLUENT_FLINK_API_SECRET="your-secret"
|
|
178
|
-
export CONFLUENT_ENV_ID="env-123456"
|
|
179
205
|
export CONFLUENT_ORG_ID="org-123456"
|
|
180
|
-
export
|
|
206
|
+
export CONFLUENT_ENV_ID="env-123456"
|
|
181
207
|
export CONFLUENT_CLOUD_PROVIDER="aws"
|
|
182
208
|
export CONFLUENT_CLOUD_REGION="us-east-2"
|
|
183
|
-
export
|
|
209
|
+
export CONFLUENT_FLINK_API_KEY="your-key" # Flink Region API key for the above cloud/region ...
|
|
210
|
+
export CONFLUENT_FLINK_API_SECRET="your-secret" # and associated secret.
|
|
211
|
+
export CONFLUENT_COMPUTE_POOL_ID="lfcp-789012" # A compute pool within the above cloud/region.
|
|
212
|
+
export CONFLUENT_TEST_DBNAME="test-db" # A database/kafka cluster name within the above cloud/region.
|
|
184
213
|
```
|
|
185
214
|
|
|
186
215
|
Run tests:
|
|
@@ -740,7 +740,7 @@ with connection.closing_streaming_cursor(as_dict=True) as cursor:
|
|
|
740
740
|
|
|
741
741
|
```python
|
|
742
742
|
cursor = connection.streaming_cursor()
|
|
743
|
-
cursor.execute("SELECT * FROM stream WHERE active = %s", (True,),
|
|
743
|
+
cursor.execute("SELECT * FROM stream WHERE active = %s", (True,), statement_labels=["my-streaming-job"])
|
|
744
744
|
|
|
745
745
|
# Query statement information
|
|
746
746
|
print(f"Statement name: {cursor.statement.name}")
|
|
@@ -15,7 +15,7 @@ if __name__ == "__main__":
|
|
|
15
15
|
conn = confluent_sql.connect(
|
|
16
16
|
flink_api_key=os.getenv("CONFLUENT_FLINK_API_KEY", ""),
|
|
17
17
|
flink_api_secret=os.getenv("CONFLUENT_FLINK_API_SECRET", ""),
|
|
18
|
-
|
|
18
|
+
environment_id=os.getenv("CONFLUENT_ENV_ID", ""),
|
|
19
19
|
organization_id=os.getenv("CONFLUENT_ORG_ID", ""),
|
|
20
20
|
compute_pool_id=os.getenv("CONFLUENT_COMPUTE_POOL_ID", ""),
|
|
21
21
|
cloud_provider=os.getenv("CONFLUENT_CLOUD_PROVIDER", "aws"),
|
{confluent_sql-0.2.0 → confluent_sql-0.3.0}/examples/simple_append_only_streaming_query_example.py
RENAMED
|
@@ -8,7 +8,7 @@ import confluent_sql
|
|
|
8
8
|
conn = confluent_sql.connect(
|
|
9
9
|
flink_api_key=os.getenv("CONFLUENT_FLINK_API_KEY", ""),
|
|
10
10
|
flink_api_secret=os.getenv("CONFLUENT_FLINK_API_SECRET", ""),
|
|
11
|
-
|
|
11
|
+
environment_id=os.getenv("CONFLUENT_ENV_ID", ""),
|
|
12
12
|
organization_id=os.getenv("CONFLUENT_ORG_ID", ""),
|
|
13
13
|
compute_pool_id=os.getenv("CONFLUENT_COMPUTE_POOL_ID", ""),
|
|
14
14
|
cloud_provider=os.getenv("CONFLUENT_CLOUD_PROVIDER", ""),
|
{confluent_sql-0.2.0 → confluent_sql-0.3.0}/examples/snapshot_mode_tuple_cursor_simple_example.py
RENAMED
|
@@ -7,7 +7,7 @@ import confluent_sql
|
|
|
7
7
|
conn = confluent_sql.connect(
|
|
8
8
|
flink_api_key=os.getenv("CONFLUENT_FLINK_API_KEY", ""),
|
|
9
9
|
flink_api_secret=os.getenv("CONFLUENT_FLINK_API_SECRET", ""),
|
|
10
|
-
|
|
10
|
+
environment_id=os.getenv("CONFLUENT_ENV_ID", ""),
|
|
11
11
|
organization_id=os.getenv("CONFLUENT_ORG_ID", ""),
|
|
12
12
|
compute_pool_id=os.getenv("CONFLUENT_COMPUTE_POOL_ID", ""),
|
|
13
13
|
cloud_provider=os.getenv("CONFLUENT_CLOUD_PROVIDER", ""),
|
|
@@ -20,13 +20,14 @@ from .exceptions import (
|
|
|
20
20
|
OperationalError,
|
|
21
21
|
ProgrammingError,
|
|
22
22
|
StatementDeletedError,
|
|
23
|
+
StatementNotFoundError,
|
|
23
24
|
StatementStoppedError,
|
|
24
25
|
TypeMismatchError,
|
|
25
26
|
Warning,
|
|
26
27
|
)
|
|
27
28
|
from .execution_mode import ExecutionMode
|
|
28
29
|
from .result_readers import ChangeloggedRow
|
|
29
|
-
from .statement import Op
|
|
30
|
+
from .statement import HIDDEN_LABEL, Op
|
|
30
31
|
from .types import PropertiesDict, SqlNone, YearMonthInterval
|
|
31
32
|
|
|
32
33
|
# DB-API v2 module globals
|
|
@@ -51,6 +52,7 @@ __all__ = [
|
|
|
51
52
|
"ComputePoolExhaustedError",
|
|
52
53
|
"StatementStoppedError",
|
|
53
54
|
"StatementDeletedError",
|
|
55
|
+
"StatementNotFoundError",
|
|
54
56
|
"IntegrityError",
|
|
55
57
|
"InternalError",
|
|
56
58
|
"ProgrammingError",
|
|
@@ -62,4 +64,5 @@ __all__ = [
|
|
|
62
64
|
"PropertiesDict",
|
|
63
65
|
"SqlNone",
|
|
64
66
|
"YearMonthInterval",
|
|
67
|
+
"HIDDEN_LABEL",
|
|
65
68
|
]
|