22from pathlib import Path
33import pytest
44from humanloop import Humanloop , FileType , AgentResponse , PromptResponse
5+ from humanloop .prompts .client import PromptsClient
6+ from humanloop .agents .client import AgentsClient
57from humanloop .error import HumanloopRuntimeError
8+ from tests .custom .types import GetHumanloopClientFn
9+ import logging
610
711
812class SyncableFile (NamedTuple ):
@@ -15,7 +19,8 @@ class SyncableFile(NamedTuple):
1519
1620@pytest .fixture
1721def test_file_structure (
18- humanloop_test_client : Humanloop , sdk_test_dir : str
22+ get_humanloop_client : GetHumanloopClientFn ,
23+ sdk_test_dir : str ,
1924) -> Generator [list [SyncableFile ], None , None ]:
2025 """Creates a predefined structure of files in Humanloop for testing sync"""
2126 files : List [SyncableFile ] = [
@@ -46,18 +51,20 @@ def test_file_structure(
4651 ),
4752 ]
4853
54+ humanloop_client : Humanloop = get_humanloop_client ()
55+
4956 # Create the files in Humanloop
5057 created_files = []
5158 for file in files :
5259 full_path = f"{ sdk_test_dir } /{ file .path } "
5360 response : Union [AgentResponse , PromptResponse ]
5461 if file .type == "prompt" :
55- response = humanloop_test_client .prompts .upsert (
62+ response = humanloop_client .prompts .upsert (
5663 path = full_path ,
5764 model = file .model ,
5865 )
5966 elif file .type == "agent" :
60- response = humanloop_test_client .agents .upsert (
67+ response = humanloop_client .agents .upsert (
6168 path = full_path ,
6269 model = file .model ,
6370 )
@@ -82,10 +89,14 @@ def cleanup_local_files():
8289 shutil .rmtree (local_dir )
8390
8491
85- def test_pull_basic (humanloop_test_client : Humanloop , test_file_structure : List [SyncableFile ]):
92+ def test_pull_basic (
93+ get_humanloop_client : GetHumanloopClientFn ,
94+ test_file_structure : List [SyncableFile ],
95+ ):
8696 """Test that humanloop.sync() correctly syncs remote files to local filesystem"""
8797 # Run the sync
88- successful_files = humanloop_test_client .pull ()
98+ humanloop_client = get_humanloop_client ()
99+ successful_files = humanloop_client .pull ()
89100
90101 # Verify each file was synced correctly
91102 for file in test_file_structure :
@@ -105,7 +116,7 @@ def test_pull_basic(humanloop_test_client: Humanloop, test_file_structure: List[
105116
106117
107118def test_overload_with_local_files (
108- humanloop_test_client : Humanloop ,
119+ get_humanloop_client : GetHumanloopClientFn ,
109120 test_file_structure : List [SyncableFile ],
110121):
111122 """Test that overload_with_local_files correctly handles local files.
@@ -116,7 +127,8 @@ def test_overload_with_local_files(
116127 3. Test using the pulled files
117128 """
118129 # First pull the files locally
119- humanloop_test_client .pull ()
130+ humanloop_client = get_humanloop_client (use_local_files = True )
131+ humanloop_client .pull ()
120132
121133 # Test using the pulled files
122134 test_file = test_file_structure [0 ] # Use the first test file
@@ -130,30 +142,31 @@ def test_overload_with_local_files(
130142 # Test call with pulled file
131143 response : Union [AgentResponse , PromptResponse ]
132144 if test_file .type == "prompt" :
133- response = humanloop_test_client .prompts .call ( # type: ignore [assignment]
145+ response = humanloop_client .prompts .call ( # type: ignore [assignment]
134146 path = test_file .path , messages = [{"role" : "user" , "content" : "Testing" }]
135147 )
136148 assert response is not None
137149 elif test_file .type == "agent" :
138- response = humanloop_test_client .agents .call ( # type: ignore [assignment]
150+ response = humanloop_client .agents .call ( # type: ignore [assignment]
139151 path = test_file .path , messages = [{"role" : "user" , "content" : "Testing" }]
140152 )
141153 assert response is not None
142154
143155 # Test with invalid path
144156 with pytest .raises (HumanloopRuntimeError ):
157+ sub_client : Union [PromptsClient , AgentsClient ]
145158 match test_file .type :
146159 case "prompt" :
147- sub_agent = humanloop_test_client . agents
160+ sub_client = humanloop_client . prompts
148161 case "agent" :
149- sub_agent = humanloop_test_client .agents
162+ sub_client = humanloop_client .agents
150163 case _:
151164 raise ValueError (f"Invalid file type: { test_file .type } " )
152- sub_agent .call (path = "invalid/path" )
165+ sub_client .call (path = "invalid/path" )
153166
154167
155168def test_overload_log_with_local_files (
156- humanloop_test_client : Humanloop ,
169+ get_humanloop_client : GetHumanloopClientFn ,
157170 test_file_structure : List [SyncableFile ],
158171 sdk_test_dir : str ,
159172):
@@ -169,7 +182,8 @@ def test_overload_log_with_local_files(
169182 :param cleanup_local_files: Fixture to clean up local files after test
170183 """
171184 # First pull the files locally
172- humanloop_test_client .pull ()
185+ humanloop_client = get_humanloop_client (use_local_files = True )
186+ humanloop_client .pull ()
173187
174188 # Test using the pulled files
175189 test_file = test_file_structure [0 ] # Use the first test file
@@ -182,34 +196,36 @@ def test_overload_log_with_local_files(
182196
183197 # Test log with pulled file
184198 if test_file .type == "prompt" :
185- response = humanloop_test_client .prompts .log ( # type: ignore [assignment]
199+ response = humanloop_client .prompts .log ( # type: ignore [assignment]
186200 path = test_file .path , messages = [{"role" : "user" , "content" : "Testing" }], output = "Test response"
187201 )
188202 assert response is not None
189203 elif test_file .type == "agent" :
190- response = humanloop_test_client .agents .log ( # type: ignore [assignment]
204+ response = humanloop_client .agents .log ( # type: ignore [assignment]
191205 path = test_file .path , messages = [{"role" : "user" , "content" : "Testing" }], output = "Test response"
192206 )
193207 assert response is not None
194208
195209 # Test with invalid path
196210 with pytest .raises (HumanloopRuntimeError ):
197211 if test_file .type == "prompt" :
198- humanloop_test_client .prompts .log (
212+ humanloop_client .prompts .log (
199213 path = f"{ sdk_test_dir } /invalid/path" ,
200214 messages = [{"role" : "user" , "content" : "Testing" }],
201215 output = "Test response" ,
202216 )
203217 elif test_file .type == "agent" :
204- humanloop_test_client .agents .log (
218+ humanloop_client .agents .log (
205219 path = f"{ sdk_test_dir } /invalid/path" ,
206220 messages = [{"role" : "user" , "content" : "Testing" }],
207221 output = "Test response" ,
208222 )
209223
210224
211225def test_overload_version_environment_handling (
212- humanloop_test_client : Humanloop , test_file_structure : List [SyncableFile ]
226+ caplog : pytest .LogCaptureFixture ,
227+ get_humanloop_client : GetHumanloopClientFn ,
228+ test_file_structure : List [SyncableFile ],
213229):
214230 """Test that overload_with_local_files correctly handles version_id and environment parameters.
215231
@@ -219,7 +235,8 @@ def test_overload_version_environment_handling(
219235 3. Test that version_id/environment parameters cause remote usage with warning
220236 """
221237 # First pull the files locally
222- humanloop_test_client .pull ()
238+ humanloop_client = get_humanloop_client (use_local_files = True )
239+ humanloop_client .pull ()
223240
224241 # Test using the pulled files
225242 test_file = test_file_structure [0 ] # Use the first test file
@@ -231,47 +248,46 @@ def test_overload_version_environment_handling(
231248 assert local_path .parent .exists (), f"Expected directory at { local_path .parent } "
232249
233250 # Test with version_id - should use remote with warning
234- with pytest .warns (UserWarning , match = "Ignoring local file.*as version_id or environment was specified" ):
251+ # Check that the warning was logged
252+ with caplog .at_level (level = logging .WARNING , logger = "humanloop.sdk" ):
235253 if test_file .type == "prompt" :
236- response = humanloop_test_client .prompts .call ( # type: ignore [assignment]
254+ response = humanloop_client .prompts .call (
237255 path = test_file .path ,
238256 version_id = test_file .version_id ,
239257 messages = [{"role" : "user" , "content" : "Testing" }],
240258 )
241259 elif test_file .type == "agent" :
242- response = humanloop_test_client .agents .call ( # type: ignore [assignment]
260+ response = humanloop_client .agents .call ( # type: ignore [assignment]
243261 path = test_file .path ,
244262 version_id = test_file .version_id ,
245263 messages = [{"role" : "user" , "content" : "Testing" }],
246264 )
247265 assert response is not None
266+ assert any (["Ignoring local file" in record .message for record in caplog .records ])
248267
249268 # Test with environment - should use remote with warning
250- with pytest .warns (UserWarning , match = "Ignoring local file.*as version_id or environment was specified" ):
251- if test_file .type == "prompt" :
252- response = humanloop_test_client .prompts .call ( # type: ignore [assignment]
253- path = test_file .path , environment = "production" , messages = [{"role" : "user" , "content" : "Testing" }]
254- )
255- elif test_file .type == "agent" :
256- response = humanloop_test_client .agents .call ( # type: ignore [assignment]
257- path = test_file .path , environment = "production" , messages = [{"role" : "user" , "content" : "Testing" }]
258- )
259- assert response is not None
269+ if test_file .type == "prompt" :
270+ response = humanloop_client .prompts .call ( # type: ignore [assignment]
271+ path = test_file .path , environment = "production" , messages = [{"role" : "user" , "content" : "Testing" }]
272+ )
273+ elif test_file .type == "agent" :
274+ response = humanloop_client .agents .call ( # type: ignore [assignment]
275+ path = test_file .path , environment = "production" , messages = [{"role" : "user" , "content" : "Testing" }]
276+ )
277+ assert response is not None
260278
261- # Test with both version_id and environment - should use remote with warning
262- with pytest .warns (UserWarning , match = "Ignoring local file.*as version_id or environment was specified" ):
263- if test_file .type == "prompt" :
264- response = humanloop_test_client .prompts .call ( # type: ignore [assignment]
265- path = test_file .path ,
266- version_id = test_file .version_id ,
267- environment = "staging" ,
268- messages = [{"role" : "user" , "content" : "Testing" }],
269- )
270- elif test_file .type == "agent" :
271- response = humanloop_test_client .agents .call ( # type: ignore [assignment]
272- path = test_file .path ,
273- version_id = test_file .version_id ,
274- environment = "staging" ,
275- messages = [{"role" : "user" , "content" : "Testing" }],
276- )
277- assert response is not None
279+ if test_file .type == "prompt" :
280+ response = humanloop_client .prompts .call ( # type: ignore [assignment]
281+ path = test_file .path ,
282+ version_id = test_file .version_id ,
283+ environment = "staging" ,
284+ messages = [{"role" : "user" , "content" : "Testing" }],
285+ )
286+ elif test_file .type == "agent" :
287+ response = humanloop_client .agents .call ( # type: ignore [assignment]
288+ path = test_file .path ,
289+ version_id = test_file .version_id ,
290+ environment = "staging" ,
291+ messages = [{"role" : "user" , "content" : "Testing" }],
292+ )
293+ assert response is not None
0 commit comments