duckrun 0.2.10__tar.gz → 0.2.10.dev0__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.

Potentially problematic release.


This version of duckrun might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: duckrun
3
- Version: 0.2.10
3
+ Version: 0.2.10.dev0
4
4
  Summary: Lakehouse task runner powered by DuckDB for Microsoft Fabric
5
5
  Author: mim
6
6
  License: MIT
@@ -456,6 +456,154 @@ class Duckrun:
456
456
  except Exception as e:
457
457
  print(f"❌ Error attaching lakehouse: {e}")
458
458
  print("Continuing without pre-attached tables.")
459
+
460
+ # Register lookup functions as DuckDB UDFs
461
+ self._register_lookup_functions()
462
+
463
+ def _register_lookup_functions(self):
464
+ """
465
+ Register Fabric API lookup functions as DuckDB UDFs.
466
+ Allows SQL queries to resolve workspace/lakehouse names from IDs and vice versa.
467
+
468
+ Functions registered:
469
+ - get_workspace_name(workspace_id) -> str
470
+ - get_lakehouse_name(workspace_id, lakehouse_id) -> str
471
+ - get_workspace_id_from_name(workspace_name) -> str
472
+ - get_lakehouse_id_from_name(workspace_id, lakehouse_name) -> str
473
+ """
474
+ # Cache to avoid repeated API calls
475
+ self._name_cache = {
476
+ 'workspace_id_to_name': {},
477
+ 'workspace_name_to_id': {},
478
+ 'lakehouse_id_to_name': {},
479
+ 'lakehouse_name_to_id': {}
480
+ }
481
+
482
+ def get_workspace_name(workspace_id: str) -> str:
483
+ """Get workspace display name from workspace ID (GUID)"""
484
+ if workspace_id in self._name_cache['workspace_id_to_name']:
485
+ return self._name_cache['workspace_id_to_name'][workspace_id]
486
+
487
+ try:
488
+ from .auth import get_fabric_api_token
489
+ token = get_fabric_api_token()
490
+ if not token:
491
+ return f"[Error: No auth token]"
492
+
493
+ url = "https://api.fabric.microsoft.com/v1/workspaces"
494
+ headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
495
+ response = requests.get(url, headers=headers)
496
+ response.raise_for_status()
497
+
498
+ workspaces = response.json().get("value", [])
499
+ for workspace in workspaces:
500
+ if workspace.get("id") == workspace_id:
501
+ name = workspace.get("displayName", "")
502
+ self._name_cache['workspace_id_to_name'][workspace_id] = name
503
+ self._name_cache['workspace_name_to_id'][name] = workspace_id
504
+ return name
505
+
506
+ return f"[Workspace {workspace_id} not found]"
507
+ except Exception as e:
508
+ return f"[Error: {str(e)}]"
509
+
510
+ def get_lakehouse_name(workspace_id: str, lakehouse_id: str) -> str:
511
+ """Get lakehouse display name from workspace ID and lakehouse ID (GUIDs)"""
512
+ cache_key = f"{workspace_id}/{lakehouse_id}"
513
+ if cache_key in self._name_cache['lakehouse_id_to_name']:
514
+ return self._name_cache['lakehouse_id_to_name'][cache_key]
515
+
516
+ try:
517
+ from .auth import get_fabric_api_token
518
+ token = get_fabric_api_token()
519
+ if not token:
520
+ return f"[Error: No auth token]"
521
+
522
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{workspace_id}/lakehouses"
523
+ headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
524
+ response = requests.get(url, headers=headers)
525
+ response.raise_for_status()
526
+
527
+ lakehouses = response.json().get("value", [])
528
+ for lakehouse in lakehouses:
529
+ if lakehouse.get("id") == lakehouse_id:
530
+ name = lakehouse.get("displayName", "")
531
+ self._name_cache['lakehouse_id_to_name'][cache_key] = name
532
+ lh_cache_key = f"{workspace_id}/{name}"
533
+ self._name_cache['lakehouse_name_to_id'][lh_cache_key] = lakehouse_id
534
+ return name
535
+
536
+ return f"[Lakehouse {lakehouse_id} not found]"
537
+ except Exception as e:
538
+ return f"[Error: {str(e)}]"
539
+
540
+ def get_workspace_id_from_name(workspace_name: str) -> str:
541
+ """Get workspace ID (GUID) from workspace display name"""
542
+ if workspace_name in self._name_cache['workspace_name_to_id']:
543
+ return self._name_cache['workspace_name_to_id'][workspace_name]
544
+
545
+ try:
546
+ from .auth import get_fabric_api_token
547
+ token = get_fabric_api_token()
548
+ if not token:
549
+ return f"[Error: No auth token]"
550
+
551
+ url = "https://api.fabric.microsoft.com/v1/workspaces"
552
+ headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
553
+ response = requests.get(url, headers=headers)
554
+ response.raise_for_status()
555
+
556
+ workspaces = response.json().get("value", [])
557
+ for workspace in workspaces:
558
+ if workspace.get("displayName") == workspace_name:
559
+ workspace_id = workspace.get("id", "")
560
+ self._name_cache['workspace_name_to_id'][workspace_name] = workspace_id
561
+ self._name_cache['workspace_id_to_name'][workspace_id] = workspace_name
562
+ return workspace_id
563
+
564
+ return f"[Workspace '{workspace_name}' not found]"
565
+ except Exception as e:
566
+ return f"[Error: {str(e)}]"
567
+
568
+ def get_lakehouse_id_from_name(workspace_id: str, lakehouse_name: str) -> str:
569
+ """Get lakehouse ID (GUID) from workspace ID and lakehouse display name"""
570
+ cache_key = f"{workspace_id}/{lakehouse_name}"
571
+ if cache_key in self._name_cache['lakehouse_name_to_id']:
572
+ return self._name_cache['lakehouse_name_to_id'][cache_key]
573
+
574
+ try:
575
+ from .auth import get_fabric_api_token
576
+ token = get_fabric_api_token()
577
+ if not token:
578
+ return f"[Error: No auth token]"
579
+
580
+ url = f"https://api.fabric.microsoft.com/v1/workspaces/{workspace_id}/lakehouses"
581
+ headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
582
+ response = requests.get(url, headers=headers)
583
+ response.raise_for_status()
584
+
585
+ lakehouses = response.json().get("value", [])
586
+ for lakehouse in lakehouses:
587
+ if lakehouse.get("displayName") == lakehouse_name:
588
+ lakehouse_id = lakehouse.get("id", "")
589
+ self._name_cache['lakehouse_name_to_id'][cache_key] = lakehouse_id
590
+ id_cache_key = f"{workspace_id}/{lakehouse_id}"
591
+ self._name_cache['lakehouse_id_to_name'][id_cache_key] = lakehouse_name
592
+ return lakehouse_id
593
+
594
+ return f"[Lakehouse '{lakehouse_name}' not found]"
595
+ except Exception as e:
596
+ return f"[Error: {str(e)}]"
597
+
598
+ # Register functions in DuckDB
599
+ try:
600
+ self.con.create_function("get_workspace_name", get_workspace_name)
601
+ self.con.create_function("get_lakehouse_name", get_lakehouse_name)
602
+ self.con.create_function("get_workspace_id_from_name", get_workspace_id_from_name)
603
+ self.con.create_function("get_lakehouse_id_from_name", get_lakehouse_id_from_name)
604
+ print("✅ Registered lookup functions: get_workspace_name, get_lakehouse_name, get_workspace_id_from_name, get_lakehouse_id_from_name")
605
+ except Exception as e:
606
+ print(f"⚠️ Warning: Could not register lookup functions: {e}")
459
607
 
460
608
  def get_workspace_id(self) -> str:
461
609
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: duckrun
3
- Version: 0.2.10
3
+ Version: 0.2.10.dev0
4
4
  Summary: Lakehouse task runner powered by DuckDB for Microsoft Fabric
5
5
  Author: mim
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "duckrun"
7
- version = "0.2.10"
7
+ version = "0.2.10.dev0"
8
8
  description = "Lakehouse task runner powered by DuckDB for Microsoft Fabric"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes