griptape-nodes 0.62.0__py3-none-any.whl → 0.62.1__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.
- griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py +2 -2
- griptape_nodes/drivers/storage/local_storage_driver.py +2 -2
- griptape_nodes/retained_mode/managers/event_manager.py +24 -9
- griptape_nodes/retained_mode/managers/library_manager.py +12 -21
- griptape_nodes/retained_mode/managers/static_files_manager.py +1 -5
- {griptape_nodes-0.62.0.dist-info → griptape_nodes-0.62.1.dist-info}/METADATA +1 -1
- {griptape_nodes-0.62.0.dist-info → griptape_nodes-0.62.1.dist-info}/RECORD +9 -9
- {griptape_nodes-0.62.0.dist-info → griptape_nodes-0.62.1.dist-info}/WHEEL +1 -1
- {griptape_nodes-0.62.0.dist-info → griptape_nodes-0.62.1.dist-info}/entry_points.txt +0 -0
|
@@ -46,7 +46,7 @@ class GriptapeCloudStorageDriver(BaseStorageDriver):
|
|
|
46
46
|
response = httpx.post(url, json={"operation": "PUT"}, headers=self.headers)
|
|
47
47
|
response.raise_for_status()
|
|
48
48
|
except httpx.HTTPStatusError as e:
|
|
49
|
-
msg = f"Failed to create presigned URL for file {path}: {e}"
|
|
49
|
+
msg = f"Failed to create presigned upload URL for file {path}: {e}"
|
|
50
50
|
logger.error(msg)
|
|
51
51
|
raise RuntimeError(msg) from e
|
|
52
52
|
|
|
@@ -60,7 +60,7 @@ class GriptapeCloudStorageDriver(BaseStorageDriver):
|
|
|
60
60
|
response = httpx.post(url, json={"method": "GET"}, headers=self.headers)
|
|
61
61
|
response.raise_for_status()
|
|
62
62
|
except httpx.HTTPStatusError as e:
|
|
63
|
-
msg = f"Failed to create presigned URL for file {path}: {e}"
|
|
63
|
+
msg = f"Failed to create presigned download URL for file {path}: {e}"
|
|
64
64
|
logger.error(msg)
|
|
65
65
|
raise RuntimeError(msg) from e
|
|
66
66
|
|
|
@@ -43,14 +43,14 @@ class LocalStorageDriver(BaseStorageDriver):
|
|
|
43
43
|
response = httpx.post(static_url, json={"file_path": str(path)})
|
|
44
44
|
response.raise_for_status()
|
|
45
45
|
except httpx.HTTPStatusError as e:
|
|
46
|
-
msg = f"Failed to create
|
|
46
|
+
msg = f"Failed to create upload URL for file {path}: {e}"
|
|
47
47
|
logger.error(msg)
|
|
48
48
|
raise RuntimeError(msg) from e
|
|
49
49
|
|
|
50
50
|
response_data = response.json()
|
|
51
51
|
url = response_data.get("url")
|
|
52
52
|
if url is None:
|
|
53
|
-
msg = f"Failed to
|
|
53
|
+
msg = f"Failed to get upload URL for file {path}: {response_data}"
|
|
54
54
|
logger.error(msg)
|
|
55
55
|
raise ValueError(msg)
|
|
56
56
|
|
|
@@ -98,6 +98,19 @@ class EventManager:
|
|
|
98
98
|
self._event_loop = None
|
|
99
99
|
self._loop_thread_id = None
|
|
100
100
|
|
|
101
|
+
def _is_cross_thread_call(self) -> bool:
|
|
102
|
+
"""Check if the current call is from a different thread than the event loop.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
True if we're on a different thread and need thread-safe operations
|
|
106
|
+
"""
|
|
107
|
+
current_thread_id = threading.get_ident()
|
|
108
|
+
return (
|
|
109
|
+
self._loop_thread_id is not None
|
|
110
|
+
and current_thread_id != self._loop_thread_id
|
|
111
|
+
and self._event_loop is not None
|
|
112
|
+
)
|
|
113
|
+
|
|
101
114
|
def put_event(self, event: Any) -> None:
|
|
102
115
|
"""Put event into async queue from sync context (non-blocking).
|
|
103
116
|
|
|
@@ -109,15 +122,9 @@ class EventManager:
|
|
|
109
122
|
if self._event_queue is None:
|
|
110
123
|
return
|
|
111
124
|
|
|
112
|
-
|
|
113
|
-
current_thread_id = threading.get_ident()
|
|
114
|
-
|
|
115
|
-
if (
|
|
116
|
-
self._loop_thread_id is not None
|
|
117
|
-
and current_thread_id != self._loop_thread_id
|
|
118
|
-
and self._event_loop is not None
|
|
119
|
-
):
|
|
125
|
+
if self._is_cross_thread_call() and self._event_loop is not None:
|
|
120
126
|
# We're in a different thread from the event loop, use thread-safe method
|
|
127
|
+
# _is_cross_thread_call() guarantees _event_loop is not None
|
|
121
128
|
self._event_loop.call_soon_threadsafe(self._event_queue.put_nowait, event)
|
|
122
129
|
else:
|
|
123
130
|
# We're on the same thread as the event loop or no loop thread tracked, use direct method
|
|
@@ -126,13 +133,21 @@ class EventManager:
|
|
|
126
133
|
async def aput_event(self, event: Any) -> None:
|
|
127
134
|
"""Put event into async queue from async context.
|
|
128
135
|
|
|
136
|
+
Automatically detects if we're in a different thread and uses thread-safe operations.
|
|
137
|
+
|
|
129
138
|
Args:
|
|
130
139
|
event: The event to publish to the queue
|
|
131
140
|
"""
|
|
132
141
|
if self._event_queue is None:
|
|
133
142
|
return
|
|
134
143
|
|
|
135
|
-
|
|
144
|
+
if self._is_cross_thread_call() and self._event_loop is not None:
|
|
145
|
+
# We're in a different thread from the event loop, use thread-safe method
|
|
146
|
+
# _is_cross_thread_call() guarantees _event_loop is not None
|
|
147
|
+
self._event_loop.call_soon_threadsafe(self._event_queue.put_nowait, event)
|
|
148
|
+
else:
|
|
149
|
+
# We're on the same thread as the event loop or no loop thread tracked, use async method
|
|
150
|
+
await self._event_queue.put(event)
|
|
136
151
|
|
|
137
152
|
def assign_manager_to_request_type(
|
|
138
153
|
self,
|
|
@@ -1639,6 +1639,13 @@ class LibraryManager:
|
|
|
1639
1639
|
user_libraries_section = "app_events.on_app_initialization_complete.libraries_to_register"
|
|
1640
1640
|
libraries_to_register: list[str] = config_mgr.get_config_value(user_libraries_section)
|
|
1641
1641
|
|
|
1642
|
+
# Filter out empty or whitespace-only entries
|
|
1643
|
+
original_count = len(libraries_to_register) if libraries_to_register else 0
|
|
1644
|
+
libraries_to_register = [path for path in (libraries_to_register or []) if path and path.strip()]
|
|
1645
|
+
filtered_count = original_count - len(libraries_to_register)
|
|
1646
|
+
if filtered_count > 0:
|
|
1647
|
+
logger.warning("Filtered out %d empty library path entries from configuration", filtered_count)
|
|
1648
|
+
|
|
1642
1649
|
if not libraries_to_register:
|
|
1643
1650
|
logger.info("No libraries to register from config")
|
|
1644
1651
|
return
|
|
@@ -1986,24 +1993,6 @@ class LibraryManager:
|
|
|
1986
1993
|
ret_val.append(file_path)
|
|
1987
1994
|
return ret_val
|
|
1988
1995
|
|
|
1989
|
-
def _load_libraries_from_config_category(self, config_category: str, *, load_as_default_library: bool) -> None:
|
|
1990
|
-
config_mgr = GriptapeNodes.ConfigManager()
|
|
1991
|
-
libraries_to_register_category: list[str] = config_mgr.get_config_value(config_category)
|
|
1992
|
-
|
|
1993
|
-
if libraries_to_register_category is not None:
|
|
1994
|
-
for library_to_register in libraries_to_register_category:
|
|
1995
|
-
if library_to_register:
|
|
1996
|
-
if library_to_register.endswith(".json"):
|
|
1997
|
-
library_load_request = RegisterLibraryFromFileRequest(
|
|
1998
|
-
file_path=library_to_register,
|
|
1999
|
-
load_as_default_library=load_as_default_library,
|
|
2000
|
-
)
|
|
2001
|
-
else:
|
|
2002
|
-
library_load_request = RegisterLibraryFromRequirementSpecifierRequest(
|
|
2003
|
-
requirement_specifier=library_to_register
|
|
2004
|
-
)
|
|
2005
|
-
GriptapeNodes.handle_request(library_load_request)
|
|
2006
|
-
|
|
2007
1996
|
def _remove_missing_libraries_from_config(self, config_category: str) -> None:
|
|
2008
1997
|
# Now remove all libraries that were missing from the user's config.
|
|
2009
1998
|
config_mgr = GriptapeNodes.ConfigManager()
|
|
@@ -2076,8 +2065,10 @@ class LibraryManager:
|
|
|
2076
2065
|
# Add from config
|
|
2077
2066
|
config_libraries = config_mgr.get_config_value(user_libraries_section, default=[])
|
|
2078
2067
|
for library_path_str in config_libraries:
|
|
2079
|
-
|
|
2080
|
-
if
|
|
2081
|
-
|
|
2068
|
+
# Filter out falsy values that will resolve to current directory
|
|
2069
|
+
if library_path_str:
|
|
2070
|
+
library_path = Path(library_path_str)
|
|
2071
|
+
if library_path.exists():
|
|
2072
|
+
process_path(library_path)
|
|
2082
2073
|
|
|
2083
2074
|
return list(discovered_libraries)
|
|
@@ -104,14 +104,12 @@ class StaticFilesManager:
|
|
|
104
104
|
content_bytes = base64.b64decode(request.content)
|
|
105
105
|
except (binascii.Error, ValueError) as e:
|
|
106
106
|
msg = f"Failed to decode base64 content for file {file_name}: {e}"
|
|
107
|
-
logger.error(msg)
|
|
108
107
|
return CreateStaticFileResultFailure(error=msg, result_details=msg)
|
|
109
108
|
|
|
110
109
|
try:
|
|
111
110
|
url = self.save_static_file(content_bytes, file_name)
|
|
112
111
|
except Exception as e:
|
|
113
112
|
msg = f"Failed to create static file for file {file_name}: {e}"
|
|
114
|
-
logger.error(msg)
|
|
115
113
|
return CreateStaticFileResultFailure(error=msg, result_details=msg)
|
|
116
114
|
|
|
117
115
|
return CreateStaticFileResultSuccess(url=url, result_details=f"Successfully created static file: {url}")
|
|
@@ -137,7 +135,6 @@ class StaticFilesManager:
|
|
|
137
135
|
response = self.storage_driver.create_signed_upload_url(full_file_path)
|
|
138
136
|
except Exception as e:
|
|
139
137
|
msg = f"Failed to create presigned URL for file {file_name}: {e}"
|
|
140
|
-
logger.error(msg)
|
|
141
138
|
return CreateStaticFileUploadUrlResultFailure(error=msg, result_details=msg)
|
|
142
139
|
|
|
143
140
|
return CreateStaticFileUploadUrlResultSuccess(
|
|
@@ -168,7 +165,6 @@ class StaticFilesManager:
|
|
|
168
165
|
url = self.storage_driver.create_signed_download_url(full_file_path)
|
|
169
166
|
except Exception as e:
|
|
170
167
|
msg = f"Failed to create presigned URL for file {file_name}: {e}"
|
|
171
|
-
logger.error(msg)
|
|
172
168
|
return CreateStaticFileDownloadUrlResultFailure(error=msg, result_details=msg)
|
|
173
169
|
|
|
174
170
|
return CreateStaticFileDownloadUrlResultSuccess(
|
|
@@ -177,7 +173,7 @@ class StaticFilesManager:
|
|
|
177
173
|
|
|
178
174
|
def on_app_initialization_complete(self, _payload: AppInitializationComplete) -> None:
|
|
179
175
|
# Start static server in daemon thread if enabled
|
|
180
|
-
if self.
|
|
176
|
+
if isinstance(self.storage_driver, LocalStorageDriver):
|
|
181
177
|
threading.Thread(target=start_static_server, daemon=True, name="static-server").start()
|
|
182
178
|
|
|
183
179
|
def save_static_file(self, data: bytes, file_name: str) -> str:
|
|
@@ -54,8 +54,8 @@ griptape_nodes/common/project_templates/validation.py,sha256=LPm0gri05ZIbSfCqOM4
|
|
|
54
54
|
griptape_nodes/drivers/__init__.py,sha256=tHmiFQn6uJyFVhC2PrqHgRUH3d3yDsqMQpWqRasmaqA,42
|
|
55
55
|
griptape_nodes/drivers/storage/__init__.py,sha256=_7p8vJt3YnnF6sD3Uxxw38c-gazuMIHSS-m3G6sa2Qk,208
|
|
56
56
|
griptape_nodes/drivers/storage/base_storage_driver.py,sha256=47PrMzxOuJhV2ee4CbPT7YOqR2MjlHr3VxhGON_ygio,3945
|
|
57
|
-
griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py,sha256=
|
|
58
|
-
griptape_nodes/drivers/storage/local_storage_driver.py,sha256=
|
|
57
|
+
griptape_nodes/drivers/storage/griptape_cloud_storage_driver.py,sha256=qQctInOvfKRJdqTiW8T3ycjre2FDGTb9-JtzEtiCHVM,6870
|
|
58
|
+
griptape_nodes/drivers/storage/local_storage_driver.py,sha256=FqiX1DmvpyKx444f74cFCsQ2Mfx6XiOezRcCGFOCSgQ,3665
|
|
59
59
|
griptape_nodes/drivers/storage/storage_backend.py,sha256=3QBIwrgPc1krBIiPYLoK2swhIPDiKJnnucOEdyx7y3c,184
|
|
60
60
|
griptape_nodes/exe_types/__init__.py,sha256=wGGwKGX9-TSarUFbXpDvdU_J7eXIbWTBl_NCLOZa-G8,32
|
|
61
61
|
griptape_nodes/exe_types/connections.py,sha256=Cjt-RLjYhkTUHTrYlNIUZrYVzsyH7OXo6JO2O6exI8k,13853
|
|
@@ -131,7 +131,7 @@ griptape_nodes/retained_mode/managers/arbitrary_code_exec_manager.py,sha256=LyWz
|
|
|
131
131
|
griptape_nodes/retained_mode/managers/config_manager.py,sha256=WfzvFDPyboHgsCMpVGER6Ar1OHyPD_827LQx9xaUsMM,25573
|
|
132
132
|
griptape_nodes/retained_mode/managers/context_manager.py,sha256=eb44_CAZhCg2iYIoodlAPpYc67tG3sHyq9dPNoiq_1s,23031
|
|
133
133
|
griptape_nodes/retained_mode/managers/engine_identity_manager.py,sha256=-31364A03kU0YmAx3nM7nHdWfKnkej5Cawt_Plbwa68,10526
|
|
134
|
-
griptape_nodes/retained_mode/managers/event_manager.py,sha256=
|
|
134
|
+
griptape_nodes/retained_mode/managers/event_manager.py,sha256=a1V5lGP7B0Ts3hDvkZfmk33oESFTLP4STPUAgIU_tZU,14383
|
|
135
135
|
griptape_nodes/retained_mode/managers/flow_manager.py,sha256=YgBIPix-bFA_Htwtur83obXJWnCh5KQ7SLC1dtd0KNQ,192102
|
|
136
136
|
griptape_nodes/retained_mode/managers/library_lifecycle/__init__.py,sha256=Iq79VxTdETiExBfFWXceJggDZqS6X3OkzXE9XwFclVw,1340
|
|
137
137
|
griptape_nodes/retained_mode/managers/library_lifecycle/data_models.py,sha256=fvAP0VaYGPHYl_Kg3RL4gdJlpqya8UTvpP-C49r950k,6723
|
|
@@ -145,7 +145,7 @@ griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/packa
|
|
|
145
145
|
griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance/sandbox.py,sha256=XgG7whE74zWDxX1pOvhASW0pwjOei1EDLvIH19xdzT0,6117
|
|
146
146
|
griptape_nodes/retained_mode/managers/library_lifecycle/library_provenance.py,sha256=cCGr-MQ1RlVBiUTZepYEKdVhPgC4ebcYrmpv8rI3VeM,894
|
|
147
147
|
griptape_nodes/retained_mode/managers/library_lifecycle/library_status.py,sha256=K3UEBzAdCY9wphyBbLxDYP0Q43aYvhLZ_Pz7_SzcPec,443
|
|
148
|
-
griptape_nodes/retained_mode/managers/library_manager.py,sha256=
|
|
148
|
+
griptape_nodes/retained_mode/managers/library_manager.py,sha256=WI7nk1zBrpri8Wzq96NqfQeIWT6Av0GBfKw26xx_uEw,100965
|
|
149
149
|
griptape_nodes/retained_mode/managers/mcp_manager.py,sha256=Ezmn5_48r4JWYe-tFGqmw9dXLvvTiO1rw9b4MNCkw0U,15955
|
|
150
150
|
griptape_nodes/retained_mode/managers/model_manager.py,sha256=Qc_FiqIJQ_ZuL5Yb7WiHCgUngKlbbJ_dUo7E5Ten5_g,45036
|
|
151
151
|
griptape_nodes/retained_mode/managers/node_manager.py,sha256=7LQF3pWpTsGnQlgDu-CCeAmMk4E2VC-Ti-HiUELCkjE,196136
|
|
@@ -165,7 +165,7 @@ griptape_nodes/retained_mode/managers/resource_types/os_resource.py,sha256=ImgkO
|
|
|
165
165
|
griptape_nodes/retained_mode/managers/secrets_manager.py,sha256=2DU2002dgr3XipnAhmjqLXH82ZFb8wlGpTWX8pl4f7E,7722
|
|
166
166
|
griptape_nodes/retained_mode/managers/session_manager.py,sha256=u3OEir9rjwG7GFM4MA5crKwcwq6F-lCUKlFzxlFU4co,14085
|
|
167
167
|
griptape_nodes/retained_mode/managers/settings.py,sha256=rvWjqt82_k6fLFXXbLS_cAKNqb57_iHoVOkgZG9mnPU,9626
|
|
168
|
-
griptape_nodes/retained_mode/managers/static_files_manager.py,sha256=
|
|
168
|
+
griptape_nodes/retained_mode/managers/static_files_manager.py,sha256=zTwlvLDub5siwNIAysrtWGbls5zC2amMSP2m-M7W4v0,11170
|
|
169
169
|
griptape_nodes/retained_mode/managers/sync_manager.py,sha256=quKrg3pGEmPcoQDm5IqLHEFW64UmS4OT6o27dD57pFg,21395
|
|
170
170
|
griptape_nodes/retained_mode/managers/user_manager.py,sha256=JAOOKDhUfIbj0CJ5EHRBcplmxheQTzeogbvGO23VqXQ,4508
|
|
171
171
|
griptape_nodes/retained_mode/managers/variable_manager.py,sha256=TnuqHSRK9Yiu_EtKxQksF9SyyQb72lbFQuTQZdpBxeE,24116
|
|
@@ -210,7 +210,7 @@ griptape_nodes/version_compatibility/versions/v0_39_0/modified_parameters_set_re
|
|
|
210
210
|
griptape_nodes/version_compatibility/workflow_versions/__init__.py,sha256=z5XDgkizoNByCXpyo34hfsJKFsWlOHbD6hgzfYH9ubc,52
|
|
211
211
|
griptape_nodes/version_compatibility/workflow_versions/v0_7_0/__init__.py,sha256=IzPPmGK86h2swfGGTOHyVcBIlOng6SjgWQzlbf3ngmo,51
|
|
212
212
|
griptape_nodes/version_compatibility/workflow_versions/v0_7_0/local_executor_argument_addition.py,sha256=Y8n1wzI5a-ZCHK5eiwtnnD3zF5lN-52R67rxYn0hxyI,2069
|
|
213
|
-
griptape_nodes-0.62.
|
|
214
|
-
griptape_nodes-0.62.
|
|
215
|
-
griptape_nodes-0.62.
|
|
216
|
-
griptape_nodes-0.62.
|
|
213
|
+
griptape_nodes-0.62.1.dist-info/WHEEL,sha256=DpNsHFUm_gffZe1FgzmqwuqiuPC6Y-uBCzibcJcdupM,78
|
|
214
|
+
griptape_nodes-0.62.1.dist-info/entry_points.txt,sha256=qvevqd3BVbAV5TcantnAm0ouqaqYKhsRO3pkFymWLWM,82
|
|
215
|
+
griptape_nodes-0.62.1.dist-info/METADATA,sha256=A1IaHS65Bwx9USP7WtudGgkj63JGcDLi6ghjrmSuhUY,5178
|
|
216
|
+
griptape_nodes-0.62.1.dist-info/RECORD,,
|
|
File without changes
|