nvidia-nat-test 1.4.0a20251022__py3-none-any.whl → 1.4.0a20251024__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.
Potentially problematic release.
This version of nvidia-nat-test might be problematic. Click here for more details.
- nat/test/plugin.py +124 -14
- nat/test/utils.py +13 -21
- {nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/METADATA +2 -2
- {nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/RECORD +9 -9
- {nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/WHEEL +0 -0
- {nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/entry_points.txt +0 -0
- {nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/licenses/LICENSE-3rd-party.txt +0 -0
- {nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/licenses/LICENSE.md +0 -0
- {nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/top_level.txt +0 -0
nat/test/plugin.py
CHANGED
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
16
|
import os
|
|
17
|
+
import random
|
|
17
18
|
import subprocess
|
|
19
|
+
import time
|
|
18
20
|
import types
|
|
19
21
|
import typing
|
|
20
22
|
from collections.abc import AsyncGenerator
|
|
@@ -25,6 +27,8 @@ import pytest
|
|
|
25
27
|
import pytest_asyncio
|
|
26
28
|
|
|
27
29
|
if typing.TYPE_CHECKING:
|
|
30
|
+
import langsmith.client
|
|
31
|
+
|
|
28
32
|
from docker.client import DockerClient
|
|
29
33
|
|
|
30
34
|
|
|
@@ -220,7 +224,19 @@ def azure_openai_keys_fixture(fail_missing: bool):
|
|
|
220
224
|
yield require_env_variables(
|
|
221
225
|
varnames=["AZURE_OPENAI_API_KEY", "AZURE_OPENAI_ENDPOINT"],
|
|
222
226
|
reason="Azure integration tests require the `AZURE_OPENAI_API_KEY` and `AZURE_OPENAI_ENDPOINT` environment "
|
|
223
|
-
"
|
|
227
|
+
"variables to be defined.",
|
|
228
|
+
fail_missing=fail_missing)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
@pytest.fixture(name="langfuse_keys", scope='session')
|
|
232
|
+
def langfuse_keys_fixture(fail_missing: bool):
|
|
233
|
+
"""
|
|
234
|
+
Use for integration tests that require Langfuse credentials.
|
|
235
|
+
"""
|
|
236
|
+
yield require_env_variables(
|
|
237
|
+
varnames=["LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY"],
|
|
238
|
+
reason="Langfuse integration tests require the `LANGFUSE_PUBLIC_KEY` and `LANGFUSE_SECRET_KEY` environment "
|
|
239
|
+
"variables to be defined.",
|
|
224
240
|
fail_missing=fail_missing)
|
|
225
241
|
|
|
226
242
|
|
|
@@ -250,6 +266,40 @@ def require_weave_fixture(fail_missing: bool) -> types.ModuleType:
|
|
|
250
266
|
pytest.skip(reason=reason)
|
|
251
267
|
|
|
252
268
|
|
|
269
|
+
@pytest.fixture(name="langsmith_api_key", scope='session')
|
|
270
|
+
def langsmith_api_key_fixture(fail_missing: bool):
|
|
271
|
+
"""
|
|
272
|
+
Use for integration tests that require a LangSmith API key.
|
|
273
|
+
"""
|
|
274
|
+
yield require_env_variables(
|
|
275
|
+
varnames=["LANGSMITH_API_KEY"],
|
|
276
|
+
reason="LangSmith integration tests require the `LANGSMITH_API_KEY` environment variable to be defined.",
|
|
277
|
+
fail_missing=fail_missing)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@pytest.fixture(name="langsmith_client")
|
|
281
|
+
def langsmith_client_fixture(langsmith_api_key: str, fail_missing: bool) -> "langsmith.client.Client":
|
|
282
|
+
try:
|
|
283
|
+
import langsmith.client
|
|
284
|
+
client = langsmith.client.Client()
|
|
285
|
+
return client
|
|
286
|
+
except ImportError:
|
|
287
|
+
reason = "LangSmith integration tests require the `langsmith` package to be installed."
|
|
288
|
+
if fail_missing:
|
|
289
|
+
raise RuntimeError(reason)
|
|
290
|
+
pytest.skip(reason=reason)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@pytest.fixture(name="langsmith_project_name")
|
|
294
|
+
def langsmith_project_name_fixture(langsmith_client: "langsmith.client.Client") -> Generator[str]:
|
|
295
|
+
# Createa a unique project name for each test run
|
|
296
|
+
project_name = f"nat-e2e-test-{time.time()}-{random.random()}"
|
|
297
|
+
langsmith_client.create_project(project_name)
|
|
298
|
+
yield project_name
|
|
299
|
+
|
|
300
|
+
langsmith_client.delete_project(project_name=project_name)
|
|
301
|
+
|
|
302
|
+
|
|
253
303
|
@pytest.fixture(name="require_docker", scope='session')
|
|
254
304
|
def require_docker_fixture(fail_missing: bool) -> "DockerClient":
|
|
255
305
|
"""
|
|
@@ -298,8 +348,8 @@ def env_without_nat_log_level_fixture() -> dict[str, str]:
|
|
|
298
348
|
return env
|
|
299
349
|
|
|
300
350
|
|
|
301
|
-
@pytest.fixture(name="
|
|
302
|
-
def
|
|
351
|
+
@pytest.fixture(name="etcd_url", scope="session")
|
|
352
|
+
def etcd_url_fixture(fail_missing: bool = False) -> str:
|
|
303
353
|
"""
|
|
304
354
|
To run these tests, an etcd server must be running
|
|
305
355
|
"""
|
|
@@ -307,21 +357,22 @@ def require_etcd_fixture(fail_missing: bool = False) -> bool:
|
|
|
307
357
|
|
|
308
358
|
host = os.getenv("NAT_CI_ETCD_HOST", "localhost")
|
|
309
359
|
port = os.getenv("NAT_CI_ETCD_PORT", "2379")
|
|
310
|
-
|
|
360
|
+
url = f"http://{host}:{port}"
|
|
361
|
+
health_url = f"{url}/health"
|
|
311
362
|
|
|
312
363
|
try:
|
|
313
364
|
response = requests.get(health_url, timeout=5)
|
|
314
365
|
response.raise_for_status()
|
|
315
|
-
return
|
|
366
|
+
return url
|
|
316
367
|
except: # noqa: E722
|
|
317
|
-
failure_reason = f"Unable to connect to etcd server at {
|
|
368
|
+
failure_reason = f"Unable to connect to etcd server at {url}"
|
|
318
369
|
if fail_missing:
|
|
319
370
|
raise RuntimeError(failure_reason)
|
|
320
371
|
pytest.skip(reason=failure_reason)
|
|
321
372
|
|
|
322
373
|
|
|
323
374
|
@pytest.fixture(name="milvus_uri", scope="session")
|
|
324
|
-
def milvus_uri_fixture(
|
|
375
|
+
def milvus_uri_fixture(etcd_url: str, fail_missing: bool = False) -> str:
|
|
325
376
|
"""
|
|
326
377
|
To run these tests, a Milvus server must be running
|
|
327
378
|
"""
|
|
@@ -452,7 +503,7 @@ def fixture_redis_server(fail_missing: bool) -> Generator[dict[str, str | int]]:
|
|
|
452
503
|
pytest.skip(f"Error connecting to Redis server: {e}, skipping redis tests")
|
|
453
504
|
|
|
454
505
|
|
|
455
|
-
@pytest_asyncio.fixture(name="mysql_server", scope="
|
|
506
|
+
@pytest_asyncio.fixture(name="mysql_server", scope="session")
|
|
456
507
|
async def fixture_mysql_server(fail_missing: bool) -> AsyncGenerator[dict[str, str | int]]:
|
|
457
508
|
"""Fixture to safely skip MySQL based tests if MySQL is not running"""
|
|
458
509
|
host = os.environ.get('NAT_CI_MYSQL_HOST', '127.0.0.1')
|
|
@@ -475,7 +526,7 @@ async def fixture_mysql_server(fail_missing: bool) -> AsyncGenerator[dict[str, s
|
|
|
475
526
|
pytest.skip(f"Error connecting to MySQL server: {e}, skipping MySQL tests")
|
|
476
527
|
|
|
477
528
|
|
|
478
|
-
@pytest.fixture(name="minio_server", scope="
|
|
529
|
+
@pytest.fixture(name="minio_server", scope="session")
|
|
479
530
|
def minio_server_fixture(fail_missing: bool) -> Generator[dict[str, str | int]]:
|
|
480
531
|
"""Fixture to safely skip MinIO based tests if MinIO is not running"""
|
|
481
532
|
host = os.getenv("NAT_CI_MINIO_HOST", "localhost")
|
|
@@ -502,17 +553,76 @@ def minio_server_fixture(fail_missing: bool) -> Generator[dict[str, str | int]]:
|
|
|
502
553
|
aws_access_key_id=aws_access_key_id,
|
|
503
554
|
aws_secret_access_key=aws_secret_access_key,
|
|
504
555
|
endpoint_url=endpoint_url)
|
|
505
|
-
client.
|
|
556
|
+
client.list_buckets()
|
|
506
557
|
yield minio_info
|
|
507
558
|
except ImportError:
|
|
508
559
|
if fail_missing:
|
|
509
560
|
raise
|
|
510
561
|
pytest.skip("aioboto3 not installed, skipping MinIO tests")
|
|
511
562
|
except Exception as e:
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
563
|
+
if fail_missing:
|
|
564
|
+
raise
|
|
565
|
+
else:
|
|
566
|
+
pytest.skip(f"Error connecting to MinIO server: {e}, skipping MinIO tests")
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
@pytest.fixture(name="langfuse_bucket", scope="session")
|
|
570
|
+
def langfuse_bucket_fixture(fail_missing: bool, minio_server: dict[str, str | int]) -> Generator[str]:
|
|
571
|
+
|
|
572
|
+
bucket_name = os.getenv("NAT_CI_LANGFUSE_BUCKET", "langfuse")
|
|
573
|
+
try:
|
|
574
|
+
import botocore.session
|
|
575
|
+
session = botocore.session.get_session()
|
|
576
|
+
|
|
577
|
+
client = session.create_client("s3",
|
|
578
|
+
aws_access_key_id=minio_server["aws_access_key_id"],
|
|
579
|
+
aws_secret_access_key=minio_server["aws_secret_access_key"],
|
|
580
|
+
endpoint_url=minio_server["endpoint_url"])
|
|
581
|
+
|
|
582
|
+
buckets = client.list_buckets()
|
|
583
|
+
bucket_names = [b['Name'] for b in buckets['Buckets']]
|
|
584
|
+
if bucket_name not in bucket_names:
|
|
585
|
+
client.create_bucket(Bucket=bucket_name)
|
|
586
|
+
|
|
587
|
+
yield bucket_name
|
|
588
|
+
except ImportError:
|
|
589
|
+
if fail_missing:
|
|
590
|
+
raise
|
|
591
|
+
pytest.skip("aioboto3 not installed, skipping MinIO tests")
|
|
592
|
+
except Exception as e:
|
|
593
|
+
if fail_missing:
|
|
516
594
|
raise
|
|
517
595
|
else:
|
|
518
596
|
pytest.skip(f"Error connecting to MinIO server: {e}, skipping MinIO tests")
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
@pytest.fixture(name="langfuse_url", scope="session")
|
|
600
|
+
def langfuse_url_fixture(fail_missing: bool, langfuse_bucket: str) -> str:
|
|
601
|
+
"""
|
|
602
|
+
To run these tests, a langfuse server must be running.
|
|
603
|
+
"""
|
|
604
|
+
import requests
|
|
605
|
+
|
|
606
|
+
host = os.getenv("NAT_CI_LANGFUSE_HOST", "localhost")
|
|
607
|
+
port = int(os.getenv("NAT_CI_LANGFUSE_PORT", "3000"))
|
|
608
|
+
url = f"http://{host}:{port}"
|
|
609
|
+
health_endpoint = f"{url}/api/public/health"
|
|
610
|
+
try:
|
|
611
|
+
response = requests.get(health_endpoint, timeout=5)
|
|
612
|
+
response.raise_for_status()
|
|
613
|
+
|
|
614
|
+
return url
|
|
615
|
+
except Exception as e:
|
|
616
|
+
reason = f"Unable to connect to Langfuse server at {url}: {e}"
|
|
617
|
+
if fail_missing:
|
|
618
|
+
raise RuntimeError(reason)
|
|
619
|
+
pytest.skip(reason=reason)
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
@pytest.fixture(name="langfuse_trace_url", scope="session")
|
|
623
|
+
def langfuse_trace_url_fixture(langfuse_url: str) -> str:
|
|
624
|
+
"""
|
|
625
|
+
The langfuse_url fixture provides the base url, however the general.telemetry.tracing["langfuse"].endpoint expects
|
|
626
|
+
the trace url which is what this fixture provides.
|
|
627
|
+
"""
|
|
628
|
+
return f"{langfuse_url}/api/public/otel/v1/traces"
|
nat/test/utils.py
CHANGED
|
@@ -68,27 +68,19 @@ def locate_example_config(example_config_class: type,
|
|
|
68
68
|
return config_path
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
async def run_workflow(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
from nat.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
assert config_file is not None, "Either config_file or config must be provided"
|
|
85
|
-
assert Path(config_file).exists(), f"Config file {config_file} does not exist"
|
|
86
|
-
config = load_config(config_file)
|
|
87
|
-
|
|
88
|
-
async with WorkflowBuilder.from_config(config=config) as workflow_builder:
|
|
89
|
-
workflow = SessionManager(await workflow_builder.build())
|
|
90
|
-
async with workflow.run(question) as runner:
|
|
91
|
-
result = await runner.result(to_type=str)
|
|
71
|
+
async def run_workflow(*,
|
|
72
|
+
config: "Config | None" = None,
|
|
73
|
+
config_file: "StrPath | None" = None,
|
|
74
|
+
question: str,
|
|
75
|
+
expected_answer: str,
|
|
76
|
+
assert_expected_answer: bool = True) -> str:
|
|
77
|
+
"""
|
|
78
|
+
Test specific wrapper for `nat.utils.run_workflow` to run a workflow with a question and validate the expected
|
|
79
|
+
answer. This variant always sets the result type to `str`.
|
|
80
|
+
"""
|
|
81
|
+
from nat.utils import run_workflow as nat_run_workflow
|
|
82
|
+
|
|
83
|
+
result = await nat_run_workflow(config=config, config_file=config_file, prompt=question, to_type=str)
|
|
92
84
|
|
|
93
85
|
if assert_expected_answer:
|
|
94
86
|
assert expected_answer.lower() in result.lower(), f"Expected '{expected_answer}' in '{result}'"
|
{nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nvidia-nat-test
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.0a20251024
|
|
4
4
|
Summary: Testing utilities for NeMo Agent toolkit
|
|
5
5
|
Author: NVIDIA Corporation
|
|
6
6
|
Maintainer: NVIDIA Corporation
|
|
@@ -16,7 +16,7 @@ Requires-Python: <3.14,>=3.11
|
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE-3rd-party.txt
|
|
18
18
|
License-File: LICENSE.md
|
|
19
|
-
Requires-Dist: nvidia-nat==v1.4.
|
|
19
|
+
Requires-Dist: nvidia-nat==v1.4.0a20251024
|
|
20
20
|
Requires-Dist: langchain-community~=0.3
|
|
21
21
|
Requires-Dist: pytest~=8.3
|
|
22
22
|
Dynamic: license-file
|
{nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/RECORD
RENAMED
|
@@ -5,14 +5,14 @@ nat/test/functions.py,sha256=ZxXVzfaLBGOpR5qtmMrKU7q-M9-vVGGj3Xi5mrw4vHY,3557
|
|
|
5
5
|
nat/test/llm.py,sha256=f6bz6arAQjhjuOKFrLfu_U1LbiyFzQmpM-q8b-WKSrU,9550
|
|
6
6
|
nat/test/memory.py,sha256=xki_A2yiMhEZuQk60K7t04QRqf32nQqnfzD5Iv7fkvw,1456
|
|
7
7
|
nat/test/object_store_tests.py,sha256=PyJioOtoSzILPq6LuD-sOZ_89PIcgXWZweoHBQpK2zQ,4281
|
|
8
|
-
nat/test/plugin.py,sha256=
|
|
8
|
+
nat/test/plugin.py,sha256=VbKEduSIll8TlyKQtLX5LJ0LzCyXQDwCTxeirZKnrMY,22257
|
|
9
9
|
nat/test/register.py,sha256=o1BEA5fyxyFyCxXhQ6ArmtuNpgRyTEfvw6HdBgECPLI,897
|
|
10
10
|
nat/test/tool_test_runner.py,sha256=SxavwXHkvCQDl_PUiiiqgvGfexKJJTeBdI5i1qk6AzI,21712
|
|
11
|
-
nat/test/utils.py,sha256=
|
|
12
|
-
nvidia_nat_test-1.4.
|
|
13
|
-
nvidia_nat_test-1.4.
|
|
14
|
-
nvidia_nat_test-1.4.
|
|
15
|
-
nvidia_nat_test-1.4.
|
|
16
|
-
nvidia_nat_test-1.4.
|
|
17
|
-
nvidia_nat_test-1.4.
|
|
18
|
-
nvidia_nat_test-1.4.
|
|
11
|
+
nat/test/utils.py,sha256=x0xi3Oo2CYKqQdJ2nKqr9HvzBN6snjwzKGbVTOneqRs,5731
|
|
12
|
+
nvidia_nat_test-1.4.0a20251024.dist-info/licenses/LICENSE-3rd-party.txt,sha256=fOk5jMmCX9YoKWyYzTtfgl-SUy477audFC5hNY4oP7Q,284609
|
|
13
|
+
nvidia_nat_test-1.4.0a20251024.dist-info/licenses/LICENSE.md,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
|
14
|
+
nvidia_nat_test-1.4.0a20251024.dist-info/METADATA,sha256=XbMMIEco3xAp5nx7PzeNaNnuyUyyhp7-mAqWvt3vFno,1925
|
|
15
|
+
nvidia_nat_test-1.4.0a20251024.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
+
nvidia_nat_test-1.4.0a20251024.dist-info/entry_points.txt,sha256=7dOP9XB6iMDqvav3gYx9VWUwA8RrFzhbAa8nGeC8e4Y,99
|
|
17
|
+
nvidia_nat_test-1.4.0a20251024.dist-info/top_level.txt,sha256=8-CJ2cP6-f0ZReXe5Hzqp-5pvzzHz-5Ds5H2bGqh1-U,4
|
|
18
|
+
nvidia_nat_test-1.4.0a20251024.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nvidia_nat_test-1.4.0a20251022.dist-info → nvidia_nat_test-1.4.0a20251024.dist-info}/top_level.txt
RENAMED
|
File without changes
|