signalpilot-ai-internal 0.3.3__py3-none-any.whl → 0.4.0__py3-none-any.whl

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.

Potentially problematic release.


This version of signalpilot-ai-internal might be problematic. Click here for more details.

Files changed (41) hide show
  1. signalpilot_ai_internal/_version.py +1 -1
  2. signalpilot_ai_internal/cache_service.py +1 -4
  3. signalpilot_ai_internal/snowflake_schema_service.py +52 -20
  4. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/package.json +2 -2
  5. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/schemas/signalpilot-ai-internal/package.json.orig +1 -1
  6. signalpilot_ai_internal-0.4.0.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/447.d8bc4aeaf8ddeacb2486.js +1 -0
  7. signalpilot_ai_internal-0.4.0.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/839.694baa59818fdf19fba9.js +1 -0
  8. signalpilot_ai_internal-0.3.3.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/remoteEntry.2e2c6ae0baa591126b0a.js → signalpilot_ai_internal-0.4.0.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/remoteEntry.a0608479b9eb7d9f9b04.js +1 -1
  9. {signalpilot_ai_internal-0.3.3.dist-info → signalpilot_ai_internal-0.4.0.dist-info}/METADATA +1 -1
  10. {signalpilot_ai_internal-0.3.3.dist-info → signalpilot_ai_internal-0.4.0.dist-info}/RECORD +39 -39
  11. signalpilot_ai_internal-0.3.3.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/447.0fea0d444fc7ba458d5a.js +0 -1
  12. signalpilot_ai_internal-0.3.3.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/839.c61f5bc4d0da4a0781d6.js +0 -1
  13. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/etc/jupyter/jupyter_server_config.d/signalpilot_ai.json +0 -0
  14. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/install.json +0 -0
  15. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/schemas/signalpilot-ai-internal/plugin.json +0 -0
  16. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/104.04e170724f369fcbaf19.js +0 -0
  17. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/104.04e170724f369fcbaf19.js.LICENSE.txt +0 -0
  18. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/122.e2dadf63dc64d7b5f1ee.js +0 -0
  19. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/220.328403b5545f268b95c6.js +0 -0
  20. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/262.726e1da31a50868cb297.js +0 -0
  21. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/280.35d8c8b68815702a5238.js +0 -0
  22. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/280.35d8c8b68815702a5238.js.LICENSE.txt +0 -0
  23. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/353.72484b768a04f89bd3dd.js +0 -0
  24. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/364.dbec4c2dc12e7b050dcc.js +0 -0
  25. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/384.fa432bdb7fb6b1c95ad6.js +0 -0
  26. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/439.37e271d7a80336daabe2.js +0 -0
  27. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/476.9b4f05a99f5003f82094.js +0 -0
  28. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/481.73c7a9290b7d35a8b9c1.js +0 -0
  29. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/512.b58fc0093d080b8ee61c.js +0 -0
  30. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/553.b4042a795c91d9ff71ef.js +0 -0
  31. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/553.b4042a795c91d9ff71ef.js.LICENSE.txt +0 -0
  32. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/606.90aaaae46b73dc3c08fb.js +0 -0
  33. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/635.9720593ee20b768da3ca.js +0 -0
  34. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/713.8e6edc9a965bdd578ca7.js +0 -0
  35. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/742.91e7b516c8699eea3373.js +0 -0
  36. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/785.3aa564fc148b37d1d719.js +0 -0
  37. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/888.34054db17bcf6e87ec95.js +0 -0
  38. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/style.js +0 -0
  39. {signalpilot_ai_internal-0.3.3.data → signalpilot_ai_internal-0.4.0.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/third-party-licenses.json +0 -0
  40. {signalpilot_ai_internal-0.3.3.dist-info → signalpilot_ai_internal-0.4.0.dist-info}/WHEEL +0 -0
  41. {signalpilot_ai_internal-0.3.3.dist-info → signalpilot_ai_internal-0.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
1
1
  # This file is auto-generated by Hatchling. As such, do not:
2
2
  # - modify
3
3
  # - track in version control e.g. be sure to add to .gitignore
4
- __version__ = VERSION = '0.3.3'
4
+ __version__ = VERSION = '0.4.0'
@@ -110,7 +110,7 @@ class RobustFileOperations:
110
110
  @staticmethod
111
111
  def safe_write_json(file_path: Path, data: Any, max_retries: int = 3) -> bool:
112
112
  """Safely write JSON data with atomic operations and backups"""
113
- print(f"Attempting to write JSON to: {file_path}")
113
+ # print(f"Attempting to write JSON to: {file_path}")
114
114
 
115
115
  if not file_path.parent.exists():
116
116
  try:
@@ -138,8 +138,6 @@ class RobustFileOperations:
138
138
 
139
139
  # Keep only the most recent backup that's at least 1 hour old
140
140
  RobustFileOperations._cleanup_backups(file_path)
141
- else:
142
- print(f"Skipping backup for {file_path} - recent backup exists")
143
141
 
144
142
  except Exception as e:
145
143
  print(f"Warning: Could not create backup for {file_path}: {e}")
@@ -165,7 +163,6 @@ class RobustFileOperations:
165
163
 
166
164
  shutil.move(str(temp_path), str(file_path))
167
165
 
168
- print(f"Successfully wrote {file_path}")
169
166
  return True
170
167
 
171
168
  except Exception as e:
@@ -4,9 +4,12 @@ Provides REST API handlers for Snowflake database schema retrieval and query exe
4
4
  Supports multiple databases within a single Snowflake connection.
5
5
 
6
6
  Behavior:
7
- - Picks the smallest RUNNING warehouse.
7
+ - If a warehouse is specified in the config, it will be used directly.
8
+ - Otherwise, picks the smallest RUNNING warehouse.
8
9
  - If none running, resumes the smallest SUSPENDED warehouse.
9
10
  - If none exist, attempts to CREATE a tiny warehouse (requires privilege).
11
+ - If a database is specified in the config, only that database will be processed.
12
+ - Otherwise, all accessible databases will be processed.
10
13
  - Builds a catalog with parallel schema processing for performance.
11
14
  - For each table, includes detailed column information: name, type, ordinal position,
12
15
  nullable, description, default value, and type-specific attributes.
@@ -321,26 +324,45 @@ class SnowflakeSchemaHandler(APIHandler):
321
324
  print(f"Warning: Error processing schema {db}.{schema}: {e}", file=sys.stderr)
322
325
  return {"schema": schema, "tables": [], "error": str(e)}
323
326
 
324
- def _build_catalog(self, connector, conn, max_workers: int = 5) -> Dict:
325
- """Build complete catalog with parallel schema processing"""
327
+ def _build_catalog(self, connector, conn, max_workers: int = 5, specified_database: Optional[str] = None, specified_warehouse: Optional[str] = None) -> Dict:
328
+ """Build complete catalog with parallel schema processing
329
+
330
+ Args:
331
+ connector: Snowflake connector module
332
+ conn: Active Snowflake connection
333
+ max_workers: Number of parallel workers for schema processing
334
+ specified_database: If provided, only process this database
335
+ specified_warehouse: If provided, use this warehouse (don't auto-select)
336
+ """
326
337
  cur = conn.cursor(connector.DictCursor)
327
338
  try:
328
- # 1) Ensure a small warehouse is available
329
- preferred_wh = None
330
- # Extract warehouse from conn if available
331
- try:
332
- cur.execute("SELECT CURRENT_WAREHOUSE()")
333
- row = cur.fetchone()
334
- if row:
335
- preferred_wh = row[0] if isinstance(row, tuple) else row.get("CURRENT_WAREHOUSE()")
336
- except:
337
- pass
338
-
339
- wh = self._ensure_warehouse(cur, preferred_wh)
340
- cur.execute(f'USE WAREHOUSE "{wh}"')
339
+ # 1) Handle warehouse selection
340
+ if specified_warehouse:
341
+ # Use the explicitly specified warehouse
342
+ wh = specified_warehouse
343
+ cur.execute(f'USE WAREHOUSE "{wh}"')
344
+ else:
345
+ # Auto-select a warehouse using existing logic
346
+ preferred_wh = None
347
+ # Extract warehouse from conn if available
348
+ try:
349
+ cur.execute("SELECT CURRENT_WAREHOUSE()")
350
+ row = cur.fetchone()
351
+ if row:
352
+ preferred_wh = row[0] if isinstance(row, tuple) else row.get("CURRENT_WAREHOUSE()")
353
+ except:
354
+ pass
355
+
356
+ wh = self._ensure_warehouse(cur, preferred_wh)
357
+ cur.execute(f'USE WAREHOUSE "{wh}"')
341
358
 
342
- # 2) Databases (no compute requirement, but we already have compute)
343
- dbs = self._list_databases(cur)
359
+ # 2) Handle database selection
360
+ if specified_database:
361
+ # Only process the specified database
362
+ dbs = [specified_database]
363
+ else:
364
+ # List all databases
365
+ dbs = self._list_databases(cur)
344
366
  cur.close()
345
367
 
346
368
  catalog = []
@@ -423,12 +445,22 @@ class SnowflakeSchemaHandler(APIHandler):
423
445
  conn_params = self._get_connection_params(config)
424
446
  max_workers = int(body.get('max_workers', 5))
425
447
 
426
- print(f"[SnowflakeSchemaHandler] Connecting with account={conn_params['account']}, user={conn_params['user']}, warehouse={conn_params.get('warehouse')}, role={conn_params.get('role')}")
448
+ # Extract database and warehouse from config for filtering
449
+ specified_database = config.get('database')
450
+ specified_warehouse = config.get('warehouse')
451
+
452
+ print(f"[SnowflakeSchemaHandler] Connecting with account={conn_params['account']}, user={conn_params['user']}, warehouse={conn_params.get('warehouse')}, database={conn_params.get('database')}, role={conn_params.get('role')}")
427
453
 
428
454
  connection = connector.connect(**conn_params, client_session_keep_alive=False)
429
455
 
430
456
  try:
431
- catalog = self._build_catalog(connector, connection, max_workers=max_workers)
457
+ catalog = self._build_catalog(
458
+ connector,
459
+ connection,
460
+ max_workers=max_workers,
461
+ specified_database=specified_database,
462
+ specified_warehouse=specified_warehouse
463
+ )
432
464
  result = self._format_catalog_as_json(catalog)
433
465
  self.finish(json.dumps(result, indent=2))
434
466
  finally:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalpilot-ai-internal",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "description": "SignalPilot Agent - Your Jupyter Notebook Assistant",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -133,7 +133,7 @@
133
133
  "outputDir": "signalpilot_ai_internal/labextension",
134
134
  "schemaDir": "schema",
135
135
  "_build": {
136
- "load": "static/remoteEntry.2e2c6ae0baa591126b0a.js",
136
+ "load": "static/remoteEntry.a0608479b9eb7d9f9b04.js",
137
137
  "extension": "./extension",
138
138
  "style": "./style"
139
139
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalpilot-ai-internal",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "description": "SignalPilot Agent - Your Jupyter Notebook Assistant",
5
5
  "keywords": [
6
6
  "jupyter",