Skip to content

Commit d21020a

Browse files
committed
docs: improve comment clarity
1 parent 25fce50 commit d21020a

File tree

3 files changed

+45
-9
lines changed

3 files changed

+45
-9
lines changed

src/humanloop/overload.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,23 @@ def _handle_local_files(
9191
client: Any,
9292
sync_client: SyncClient,
9393
) -> Dict[str, Any]:
94-
"""Handle local file loading."""
94+
"""Load prompt/agent file content from local filesystem into API request.
95+
96+
Retrieves the file content at the specified path and adds it to kwargs
97+
under the appropriate field ('prompt' or 'agent'), allowing local files
98+
to be used in API calls instead of fetching from Humanloop API.
99+
100+
Args:
101+
kwargs: API call arguments
102+
client: Client instance making the call
103+
sync_client: SyncClient handling local file operations
104+
105+
Returns:
106+
Updated kwargs with file content in prompt/agent field
107+
108+
Raises:
109+
HumanloopRuntimeError: On validation or file loading failures
110+
"""
95111
if "id" in kwargs:
96112
raise HumanloopRuntimeError("Can only specify one of `id` or `path`")
97113

@@ -170,11 +186,19 @@ def _overload_log(self: Any, sync_client: Optional[SyncClient], use_local_files:
170186

171187
kwargs = _handle_tracing_context(kwargs, self)
172188

173-
# Handle local files for Prompts and Agents clients
189+
# Handle loading files from local filesystem when using Prompts and Agents clients
190+
# This enables users to define prompts/agents in local files rather than fetching from the Humanloop API
174191
if use_local_files and _get_file_type_from_client(self) in SyncClient.SERIALIZABLE_FILE_TYPES:
192+
# Developer note: sync_client should always be provided during SDK initialization when
193+
# use_local_files=True. If we hit this error, there's likely an initialization issue
194+
# in Humanloop.__init__ where the sync_client wasn't properly created or passed to the
195+
# overload_client function.
175196
if sync_client is None:
176197
logger.error("sync_client is None but client has log method and use_local_files=%s", use_local_files)
177-
raise HumanloopRuntimeError("sync_client is required for clients that support local file operations")
198+
raise HumanloopRuntimeError(
199+
"SDK initialization error: sync_client is missing but required for local file operations. "
200+
"This is likely a bug in the SDK initialization - please report this issue to the Humanloop team."
201+
)
178202
kwargs = _handle_local_files(kwargs, self, sync_client)
179203

180204
kwargs, eval_callback = _handle_evaluation_context(kwargs)
@@ -194,6 +218,7 @@ def _overload_call(self: Any, sync_client: Optional[SyncClient], use_local_files
194218
try:
195219
kwargs = _handle_tracing_context(kwargs, self)
196220
if use_local_files and _get_file_type_from_client(self) in SyncClient.SERIALIZABLE_FILE_TYPES:
221+
# Same sync_client requirement as in _overload_log - see developer note there
197222
if sync_client is None:
198223
logger.error("sync_client is None but client has call method and use_local_files=%s", use_local_files)
199224
raise HumanloopRuntimeError("sync_client is required for clients that support call operations")

src/humanloop/path_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ def normalize_path(path: str, strip_extension: bool = False) -> str:
1010
if strip_extension:
1111
path_obj = path_obj.with_suffix("")
1212

13-
# Use as_posix() to normalize separators consistently
13+
# Convert path to string with forward slashes, regardless of OS
14+
# This ensures consistent path format (e.g., "path/to/resource") across Windows/Unix
1415
return path_obj.as_posix()

src/humanloop/sync/sync_client.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
if TYPE_CHECKING:
1313
from humanloop.base_client import BaseHumanloop
1414

15-
# Set up logging
15+
# Set up isolated logger for sync operations
16+
# This logger uses the "humanloop.sdk.sync" namespace, separate from the main client's logger,
17+
# allowing CLI commands and other consumers to control sync logging verbosity independently.
18+
# This approach ensures that increasing verbosity for sync operations doesn't affect
19+
# other components of the system.
1620
logger = logging.getLogger("humanloop.sdk.sync")
1721
logger.setLevel(logging.INFO)
1822
console_handler = logging.StreamHandler()
@@ -80,18 +84,25 @@ def __init__(
8084
cache_size: int = DEFAULT_CACHE_SIZE,
8185
log_level: int = logging.WARNING,
8286
):
83-
"""
87+
"""Initialize the SyncClient.
88+
8489
Parameters
8590
----------
8691
client: Humanloop client instance
8792
base_dir: Base directory for synced files (default: "humanloop")
8893
cache_size: Maximum number of files to cache (default: DEFAULT_CACHE_SIZE)
8994
log_level: Log level for logging (default: WARNING)
95+
Note: The SyncClient uses an isolated logger (humanloop.sdk.sync) separate from
96+
the main Humanloop client logger. This allows controlling the verbosity of
97+
sync operations independently from other client operations, which is particularly
98+
useful in CLI contexts where users may want detailed sync logs without affecting
99+
the main client's log level.
90100
"""
91101
self.client = client
92102
self.base_dir = Path(base_dir)
93103
self._cache_size = cache_size
94104

105+
# Set log level for the isolated SyncClient logger
95106
logger.setLevel(log_level)
96107

97108
# Create a new cached version of get_file_content with the specified cache size
@@ -156,14 +167,13 @@ def clear_cache(self) -> None:
156167
"""Clear the LRU cache."""
157168
self.get_file_content.cache_clear() # type: ignore [attr-defined]
158169

159-
160170
def is_file(self, path: str) -> bool:
161171
"""Check if the path is a file by checking for .{file_type} extension for serializable file types.
162-
172+
163173
Files are identified by having a supported extension (.prompt or .agent).
164174
This method performs case-insensitive comparison and handles whitespace.
165175
166-
Returns:
176+
Returns:
167177
bool: True if the path ends with a supported file extension
168178
"""
169179
clean_path = path.strip().lower() # Convert to lowercase for case-insensitive comparison

0 commit comments

Comments
 (0)