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.
Files changed (48) hide show
  1. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/ARCHITECTURE.md +6 -6
  2. confluent_sql-0.3.0/CHANGELOG.md +37 -0
  3. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/DBAPI_EXTENSIONS.md +51 -16
  4. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/PKG-INFO +41 -12
  5. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/README.md +40 -11
  6. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/STREAMING.md +1 -1
  7. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/examples/errors.py +1 -1
  8. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/examples/simple_append_only_streaming_query_example.py +1 -1
  9. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/examples/snapshot_mode_tuple_cursor_simple_example.py +1 -1
  10. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/pyproject.toml +1 -1
  11. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/__init__.py +4 -1
  12. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/connection.py +197 -56
  13. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/cursor.py +29 -12
  14. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/exceptions.py +40 -1
  15. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/statement.py +4 -0
  16. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/conftest.py +4 -4
  17. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/integration/conftest.py +87 -5
  18. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/integration/test_connection.py +61 -1
  19. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/integration/test_cursor.py +68 -2
  20. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_connection_unit.py +493 -36
  21. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_connection_unit_properties.py +1 -1
  22. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_cursor_unit.py +83 -0
  23. confluent_sql-0.3.0/uv.lock +439 -0
  24. confluent_sql-0.2.0/CHANGELOG.md +0 -24
  25. confluent_sql-0.2.0/uv.lock +0 -439
  26. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.github/CODEOWNERS +0 -0
  27. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.gitignore +0 -0
  28. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.semaphore/publish_to_codeartifact.yml +0 -0
  29. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.semaphore/publish_to_pypi.yml +0 -0
  30. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/.semaphore/semaphore.yml +0 -0
  31. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/LICENSE.txt +0 -0
  32. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/Makefile +0 -0
  33. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/TYPES.md +0 -0
  34. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/service.yml +0 -0
  35. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/__version__.py +0 -0
  36. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/changelog_compressor.py +0 -0
  37. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/execution_mode.py +0 -0
  38. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/result_readers.py +0 -0
  39. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/src/confluent_sql/types.py +0 -0
  40. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/__init__.py +0 -0
  41. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/integration/test_fetch.py +0 -0
  42. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/conftest.py +0 -0
  43. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_changelog_compressor_unit.py +0 -0
  44. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_changelog_unit.py +0 -0
  45. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_execution_mode_unit.py +0 -0
  46. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_result_readers_unit.py +0 -0
  47. {confluent_sql-0.2.0 → confluent_sql-0.3.0}/tests/unit/test_statement_unit.py +0 -0
  48. {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 a label
146
+ # Group multiple statements with labels
147
147
  cursor1 = connection.cursor()
148
148
  cursor1.execute(
149
149
  "SELECT COUNT(*) FROM events",
150
- statement_label="hourly-metrics"
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
- statement_label="hourly-metrics"
156
+ statement_labels=["hourly-metrics", "analytics"]
157
157
  )
158
158
 
159
- # Later, find all statements with that label to then delete
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
- statement_label="daily-jobs"
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
- - `statement_label` (str | None): Label for grouping related statements
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
- statement_label="data-pipelines"
397
+ statement_labels=["data-pipelines", "streaming"]
398
398
  )
399
399
 
400
- # Later, find all statements with this label
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
- # Execute multiple statements with same label
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
- statement_label="daily-backups"
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
- statement_label: str | None = None,
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 | Type | Default | Description |
818
- | ----------------- | --------------------------------- | ---------- | ------------------------------------------------------------------ |
819
- | `statement_text` | `str` | (required) | SQL statement to execute |
820
- | `parameters` | `tuple \| list \| None` | None | Parameter values for parameterized statements |
821
- | `timeout` | `int` | 3000 | Max seconds to wait for statement to reach RUNNING/COMPLETED phase |
822
- | `statement_name` | `str \| None` | None | Custom statement identifier (defaults to UUID) |
823
- | `statement_label` | `str \| None` | None | Label for grouping related statements |
824
- | `properties` | `dict[str, str \| int \| bool] \| None` | None | [Statement properties](#statement-properties) to set for execution |
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
- statement_label="daily-backups"
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
- statement_label="analytics"
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.2.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 Compute Pool API credentials** for Flink SQL API access: a user or service account API key and secret for the compute pool (used as HTTP Basic Auth, for example via `flink_api_key` and `flink_api_secret`).
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
- environment="env-123456",
279
- compute_pool_id="lfcp-789012",
295
+ environment_id="env-123456",
280
296
  cloud_provider="aws",
281
297
  cloud_region="us-east-2",
282
- database="your-database-name"
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 CONFLUENT_COMPUTE_POOL_ID="lfcp-789012"
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 CONFLUENT_TEST_DBNAME="test-db"
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 Compute Pool API credentials** for Flink SQL API access: a user or service account API key and secret for the compute pool (used as HTTP Basic Auth, for example via `flink_api_key` and `flink_api_secret`).
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
- environment="env-123456",
48
- compute_pool_id="lfcp-789012",
64
+ environment_id="env-123456",
49
65
  cloud_provider="aws",
50
66
  cloud_region="us-east-2",
51
- database="your-database-name"
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 CONFLUENT_COMPUTE_POOL_ID="lfcp-789012"
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 CONFLUENT_TEST_DBNAME="test-db"
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,), statement_label="my-streaming-job")
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
- environment=os.getenv("CONFLUENT_ENV_ID", ""),
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"),
@@ -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
- environment=os.getenv("CONFLUENT_ENV_ID", ""),
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", ""),
@@ -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
- environment=os.getenv("CONFLUENT_ENV_ID", ""),
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", ""),
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "confluent-sql"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "DB-API v2 compliant driver for Confluent Cloud Flink SQL"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -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
  ]