sunholo 0.124.0__py3-none-any.whl → 0.125.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.
- sunholo/database/alloydb_client.py +98 -4
- sunholo/gcs/download_url.py +1 -1
- {sunholo-0.124.0.dist-info → sunholo-0.125.0.dist-info}/METADATA +1 -1
- {sunholo-0.124.0.dist-info → sunholo-0.125.0.dist-info}/RECORD +8 -8
- {sunholo-0.124.0.dist-info → sunholo-0.125.0.dist-info}/WHEEL +0 -0
- {sunholo-0.124.0.dist-info → sunholo-0.125.0.dist-info}/entry_points.txt +0 -0
- {sunholo-0.124.0.dist-info → sunholo-0.125.0.dist-info}/licenses/LICENSE.txt +0 -0
- {sunholo-0.124.0.dist-info → sunholo-0.125.0.dist-info}/top_level.txt +0 -0
@@ -651,9 +651,102 @@ class AlloyDBClient:
|
|
651
651
|
|
652
652
|
return result
|
653
653
|
|
654
|
+
def flatten_dict(self, nested_dict, parent_key='', separator='.'):
|
655
|
+
"""
|
656
|
+
Flatten a nested dictionary into a single-level dictionary with dot notation for keys.
|
657
|
+
|
658
|
+
Args:
|
659
|
+
nested_dict (dict): The nested dictionary to flatten
|
660
|
+
parent_key (str): The parent key for the current recursion level
|
661
|
+
separator (str): The separator to use between key levels (default: '.')
|
662
|
+
|
663
|
+
Returns:
|
664
|
+
dict: A flattened dictionary with special handling for lists
|
665
|
+
"""
|
666
|
+
flattened = {}
|
667
|
+
|
668
|
+
for key, value in nested_dict.items():
|
669
|
+
# Create the new key with parent_key if it exists
|
670
|
+
new_key = f"{parent_key}{separator}{key}" if parent_key else key
|
671
|
+
|
672
|
+
# If value is a dictionary, recursively flatten it
|
673
|
+
if isinstance(value, dict):
|
674
|
+
flattened.update(self.flatten_dict(value, new_key, separator))
|
675
|
+
# Handle lists containing dictionaries or other values
|
676
|
+
elif isinstance(value, list):
|
677
|
+
# Mark lists for special processing during database insertion
|
678
|
+
# We'll use a special format to indicate this is a list that needs expansion
|
679
|
+
flattened[new_key] = {
|
680
|
+
"__is_expandable_list__": True,
|
681
|
+
"items": value
|
682
|
+
}
|
683
|
+
else:
|
684
|
+
# For simple values, just add them with the new key
|
685
|
+
flattened[new_key] = value
|
686
|
+
|
687
|
+
return flattened
|
688
|
+
|
654
689
|
async def write_data_to_table(self, table_name: str, data: dict, metadata: dict = None):
|
655
690
|
"""
|
656
|
-
Writes data to the specified table.
|
691
|
+
Writes data to the specified table, with special handling for expandable lists.
|
692
|
+
|
693
|
+
Args:
|
694
|
+
table_name (str): Name of the table
|
695
|
+
data (dict): Data to write to the table
|
696
|
+
metadata (dict, optional): Additional metadata to include
|
697
|
+
|
698
|
+
Returns:
|
699
|
+
List of results from SQL executions
|
700
|
+
"""
|
701
|
+
# Find any expandable lists in the data
|
702
|
+
expandable_lists = {}
|
703
|
+
regular_data = {}
|
704
|
+
|
705
|
+
for key, value in data.items():
|
706
|
+
if isinstance(value, dict) and value.get("__is_expandable_list__", False):
|
707
|
+
expandable_lists[key] = value["items"]
|
708
|
+
else:
|
709
|
+
regular_data[key] = value
|
710
|
+
|
711
|
+
# If no expandable lists are found, do a simple insert
|
712
|
+
if not expandable_lists:
|
713
|
+
return await self._insert_single_row(table_name, regular_data, metadata)
|
714
|
+
|
715
|
+
# For expandable lists, we need to create multiple rows
|
716
|
+
results = []
|
717
|
+
|
718
|
+
# Create combinations of rows based on expandable lists
|
719
|
+
if expandable_lists:
|
720
|
+
# Get the first expandable list to start with
|
721
|
+
primary_list_key = next(iter(expandable_lists))
|
722
|
+
primary_list = expandable_lists[primary_list_key]
|
723
|
+
|
724
|
+
# For each item in the primary list, create a new row
|
725
|
+
for item_idx, item in enumerate(primary_list):
|
726
|
+
# Create a copy of the regular data
|
727
|
+
row_data = dict(regular_data)
|
728
|
+
|
729
|
+
# Add the current item from the primary list
|
730
|
+
if isinstance(item, dict):
|
731
|
+
# If it's a dictionary, flatten it with the primary key as prefix
|
732
|
+
flattened_item = self.flatten_dict(item, primary_list_key, "_")
|
733
|
+
row_data.update(flattened_item)
|
734
|
+
else:
|
735
|
+
# If it's a simple value, just add it with the list key
|
736
|
+
row_data[primary_list_key] = item
|
737
|
+
|
738
|
+
# Add item index for reference
|
739
|
+
row_data[f"{primary_list_key}_index"] = item_idx
|
740
|
+
|
741
|
+
# Insert this row
|
742
|
+
result = await self._insert_single_row(table_name, row_data, metadata)
|
743
|
+
results.append(result)
|
744
|
+
|
745
|
+
return results
|
746
|
+
|
747
|
+
async def _insert_single_row(self, table_name: str, data: dict, metadata: dict = None):
|
748
|
+
"""
|
749
|
+
Inserts a single row of data into the specified table.
|
657
750
|
|
658
751
|
Args:
|
659
752
|
table_name (str): Name of the table
|
@@ -663,14 +756,15 @@ class AlloyDBClient:
|
|
663
756
|
Returns:
|
664
757
|
Result of SQL execution
|
665
758
|
"""
|
759
|
+
|
666
760
|
# Create copies to avoid modifying the original data
|
667
761
|
insert_data = dict(data)
|
668
762
|
|
669
763
|
# Add metadata if provided
|
670
764
|
if metadata:
|
671
|
-
insert_data["source"] = metadata.get("objectId", metadata.get("source", "
|
672
|
-
insert_data["extraction_backend"] = metadata.get("extraction_backend", "
|
673
|
-
insert_data["extraction_model"] = metadata.get("extraction_model", "
|
765
|
+
insert_data["source"] = metadata.get("objectId", metadata.get("source", "not-in-metadata"))
|
766
|
+
insert_data["extraction_backend"] = metadata.get("extraction_backend", "not-in-metadata")
|
767
|
+
insert_data["extraction_model"] = metadata.get("extraction_model", "not-in-metadata")
|
674
768
|
|
675
769
|
# Prepare column names and values for SQL
|
676
770
|
columns = [f'"{key}"' for key in insert_data.keys()]
|
sunholo/gcs/download_url.py
CHANGED
@@ -36,7 +36,7 @@ def get_image_from_gcs(gs_uri: str) -> Image.Image: # type: ignore
|
|
36
36
|
except IOError as e:
|
37
37
|
raise ValueError("Unable to open image from bytes:", e)
|
38
38
|
|
39
|
-
def get_bytes_from_gcs(gs_uri) -> Optional[bytes]:
|
39
|
+
def get_bytes_from_gcs(gs_uri: str) -> Optional[bytes]:
|
40
40
|
"""
|
41
41
|
Downloads a file from Google Cloud Storage and returns its bytes.
|
42
42
|
|
@@ -60,7 +60,7 @@ sunholo/components/retriever.py,sha256=Wmchv3huAM4w7DIS-a5Lp9Hi7M8pE6vZdxgseiT9S
|
|
60
60
|
sunholo/components/vectorstore.py,sha256=k7GS1Y5c6ZGXSDAJvyCes6dTjhDAi0fjGbVLqpyfzBc,5918
|
61
61
|
sunholo/database/__init__.py,sha256=bpB5Nk21kwqYj-qdVnvNgXjLsbflnH4g-San7OHMqR4,283
|
62
62
|
sunholo/database/alloydb.py,sha256=x1zUMB-EVWbE2Zvp4nAs2Z-tB_kOZmS45H2lwVHdYnk,11678
|
63
|
-
sunholo/database/alloydb_client.py,sha256=
|
63
|
+
sunholo/database/alloydb_client.py,sha256=s9P57k4RC_b0Dpy0rzTUHs-h9yj3ClFYL52JzXUYeU8,31487
|
64
64
|
sunholo/database/database.py,sha256=VqhZdkXUNdvWn8sUcUV3YNby1JDVf7IykPVXWBtxo9U,7361
|
65
65
|
sunholo/database/lancedb.py,sha256=DyfZntiFKBlVPaFooNN1Z6Pl-LAs4nxWKKuq8GBqN58,715
|
66
66
|
sunholo/database/static_dbs.py,sha256=8cvcMwUK6c32AS2e_WguKXWMkFf5iN3g9WHzsh0C07Q,442
|
@@ -85,7 +85,7 @@ sunholo/excel/plugin.py,sha256=TJJdcKWyqEIce1agCJImvqvNp2CvLhzi4wUmLYHcLc8,4032
|
|
85
85
|
sunholo/gcs/__init__.py,sha256=SZvbsMFDko40sIRHTHppA37IijvJTae54vrhooEF5-4,90
|
86
86
|
sunholo/gcs/add_file.py,sha256=Pd5Zc1a3gqbuBgSI-UDC2mQnYGLJbAh_-IUzkDN5s9k,8273
|
87
87
|
sunholo/gcs/download_folder.py,sha256=ijJTnS595JqZhBH8iHFErQilMbkuKgL-bnTCMLGuvlA,1614
|
88
|
-
sunholo/gcs/download_url.py,sha256=
|
88
|
+
sunholo/gcs/download_url.py,sha256=9QMEtZhrN-y1VAqvi-7Tw2GI9iRG_uuZzCg6Qhq8_yw,6421
|
89
89
|
sunholo/gcs/extract_and_sign.py,sha256=paRrTCvCN5vkQwCB7OSkxWi-pfOgOtZ0bwdXE08c3Ps,1546
|
90
90
|
sunholo/gcs/metadata.py,sha256=oQLcXi4brsZ74aegWyC1JZmhlaEV270HS5_UWtAYYWE,898
|
91
91
|
sunholo/genai/__init__.py,sha256=TV3PYHWoR4cChdmCOaYB0PtAEQ86qol9XYYEtb1JmSA,239
|
@@ -168,9 +168,9 @@ sunholo/vertex/init.py,sha256=1OQwcPBKZYBTDPdyU7IM4X4OmiXLdsNV30C-fee2scQ,2875
|
|
168
168
|
sunholo/vertex/memory_tools.py,sha256=tBZxqVZ4InTmdBvLlOYwoSEWu4-kGquc-gxDwZCC4FA,7667
|
169
169
|
sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
|
170
170
|
sunholo/vertex/type_dict_to_json.py,sha256=uTzL4o9tJRao4u-gJOFcACgWGkBOtqACmb6ihvCErL8,4694
|
171
|
-
sunholo-0.
|
172
|
-
sunholo-0.
|
173
|
-
sunholo-0.
|
174
|
-
sunholo-0.
|
175
|
-
sunholo-0.
|
176
|
-
sunholo-0.
|
171
|
+
sunholo-0.125.0.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
|
172
|
+
sunholo-0.125.0.dist-info/METADATA,sha256=NyIZ1U8SH9vnTS0ECdCISbh2o7fp0HVBMsOKRvwipkE,10001
|
173
|
+
sunholo-0.125.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
174
|
+
sunholo-0.125.0.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
|
175
|
+
sunholo-0.125.0.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
|
176
|
+
sunholo-0.125.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|