nvidia-nat-test 1.4.0a20251105__py3-none-any.whl → 1.4.0a20251107__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 +144 -0
- nat/test/utils.py +3 -2
- {nvidia_nat_test-1.4.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.dist-info}/METADATA +2 -2
- {nvidia_nat_test-1.4.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.dist-info}/RECORD +9 -9
- {nvidia_nat_test-1.4.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.dist-info}/WHEEL +0 -0
- {nvidia_nat_test-1.4.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.dist-info}/entry_points.txt +0 -0
- {nvidia_nat_test-1.4.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.dist-info}/licenses/LICENSE-3rd-party.txt +0 -0
- {nvidia_nat_test-1.4.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.dist-info}/licenses/LICENSE.md +0 -0
- {nvidia_nat_test-1.4.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.dist-info}/top_level.txt +0 -0
nat/test/plugin.py
CHANGED
|
@@ -627,3 +627,147 @@ def langfuse_trace_url_fixture(langfuse_url: str) -> str:
|
|
|
627
627
|
the trace url which is what this fixture provides.
|
|
628
628
|
"""
|
|
629
629
|
return f"{langfuse_url}/api/public/otel/v1/traces"
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
@pytest.fixture(name="oauth2_server_url", scope="session")
|
|
633
|
+
def oauth2_server_url_fixture(fail_missing: bool) -> str:
|
|
634
|
+
"""
|
|
635
|
+
To run these tests, an oauth2 server must be running.
|
|
636
|
+
"""
|
|
637
|
+
import requests
|
|
638
|
+
|
|
639
|
+
host = os.getenv("NAT_CI_OAUTH2_HOST", "localhost")
|
|
640
|
+
port = int(os.getenv("NAT_CI_OAUTH2_PORT", "5001"))
|
|
641
|
+
url = f"http://{host}:{port}"
|
|
642
|
+
try:
|
|
643
|
+
response = requests.get(url, timeout=5)
|
|
644
|
+
response.raise_for_status()
|
|
645
|
+
|
|
646
|
+
return url
|
|
647
|
+
except Exception as e:
|
|
648
|
+
reason = f"Unable to connect to OAuth2 server at {url}: {e}"
|
|
649
|
+
if fail_missing:
|
|
650
|
+
raise RuntimeError(reason)
|
|
651
|
+
pytest.skip(reason=reason)
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
@pytest.fixture(name="oauth2_client_credentials", scope="session")
|
|
655
|
+
def oauth2_client_credentials_fixture(oauth2_server_url: str, fail_missing: bool) -> dict[str, typing.Any]:
|
|
656
|
+
"""
|
|
657
|
+
Fixture to provide OAuth2 client credentials for testing
|
|
658
|
+
|
|
659
|
+
Simulates the steps a user would take in a web browser to create a new OAuth2 client as documented in:
|
|
660
|
+
examples/front_ends/simple_auth/README.md
|
|
661
|
+
"""
|
|
662
|
+
|
|
663
|
+
try:
|
|
664
|
+
import requests
|
|
665
|
+
from bs4 import BeautifulSoup
|
|
666
|
+
username = os.getenv("NAT_CI_OAUTH2_CLIENT_USERNAME", "Testy Testerson")
|
|
667
|
+
|
|
668
|
+
# This post request responds with a cookie that we need for future requests and a 302 redirect, the response
|
|
669
|
+
# for the redirected url doesn't contain the cookie, so we disable the redirect here to capture the cookie
|
|
670
|
+
user_create_response = requests.post(oauth2_server_url,
|
|
671
|
+
data=[("username", username)],
|
|
672
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
673
|
+
allow_redirects=False,
|
|
674
|
+
timeout=5)
|
|
675
|
+
user_create_response.raise_for_status()
|
|
676
|
+
cookies = user_create_response.cookies
|
|
677
|
+
|
|
678
|
+
client_create_response = requests.post(f"{oauth2_server_url}/create_client",
|
|
679
|
+
cookies=cookies,
|
|
680
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
681
|
+
data=[
|
|
682
|
+
("client_name", "test"),
|
|
683
|
+
("client_uri", "https://test.com"),
|
|
684
|
+
("scope", "openid profile email"),
|
|
685
|
+
("redirect_uri", "http://localhost:8000/auth/redirect"),
|
|
686
|
+
("grant_type", "authorization_code\nrefresh_token"),
|
|
687
|
+
("response_type", "code"),
|
|
688
|
+
("token_endpoint_auth_method", "client_secret_post"),
|
|
689
|
+
],
|
|
690
|
+
timeout=5)
|
|
691
|
+
client_create_response.raise_for_status()
|
|
692
|
+
|
|
693
|
+
# Unfortunately the response is HTML so we need to parse it to get the client ID and secret, which are not
|
|
694
|
+
# locatable via ID tags
|
|
695
|
+
soup = BeautifulSoup(client_create_response.text, 'html.parser')
|
|
696
|
+
strong_tags = soup.find_all('strong')
|
|
697
|
+
i = 0
|
|
698
|
+
client_id = None
|
|
699
|
+
client_secret = None
|
|
700
|
+
while i < len(strong_tags) and None in (client_id, client_secret):
|
|
701
|
+
tag = strong_tags[i]
|
|
702
|
+
contents = "".join(tag.contents)
|
|
703
|
+
if client_id is None and "client_id:" in contents:
|
|
704
|
+
client_id = tag.next_sibling.strip()
|
|
705
|
+
elif client_secret is None and "client_secret:" in contents:
|
|
706
|
+
client_secret = tag.next_sibling.strip()
|
|
707
|
+
|
|
708
|
+
i += 1
|
|
709
|
+
|
|
710
|
+
assert client_id is not None and client_secret is not None, "Failed to parse client credentials from response"
|
|
711
|
+
|
|
712
|
+
return {
|
|
713
|
+
"id": client_id,
|
|
714
|
+
"secret": client_secret,
|
|
715
|
+
"username": username,
|
|
716
|
+
"url": oauth2_server_url,
|
|
717
|
+
"cookies": cookies
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
except Exception as e:
|
|
721
|
+
reason = f"Unable to create OAuth2 client: {e}"
|
|
722
|
+
if fail_missing:
|
|
723
|
+
raise RuntimeError(reason)
|
|
724
|
+
pytest.skip(reason=reason)
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
@pytest.fixture(name="local_sandbox_url", scope="session")
|
|
728
|
+
def local_sandbox_url_fixture(fail_missing: bool) -> str:
|
|
729
|
+
"""Check if sandbox server is running before running tests."""
|
|
730
|
+
import requests
|
|
731
|
+
url = os.environ.get("NAT_CI_SANDBOX_URL", "http://127.0.0.1:6000")
|
|
732
|
+
try:
|
|
733
|
+
response = requests.get(url, timeout=5)
|
|
734
|
+
response.raise_for_status()
|
|
735
|
+
return url
|
|
736
|
+
except Exception:
|
|
737
|
+
reason = (f"Sandbox server is not running at {url}. "
|
|
738
|
+
"Please start it with: cd src/nat/tool/code_execution/local_sandbox && ./start_local_sandbox.sh")
|
|
739
|
+
if fail_missing:
|
|
740
|
+
raise RuntimeError(reason)
|
|
741
|
+
pytest.skip(reason)
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
@pytest.fixture(name="sandbox_config", scope="session")
|
|
745
|
+
def sandbox_config_fixture(local_sandbox_url: str) -> dict[str, typing.Any]:
|
|
746
|
+
"""Configuration for sandbox testing."""
|
|
747
|
+
return {
|
|
748
|
+
"base_url": local_sandbox_url,
|
|
749
|
+
"execute_url": f"{local_sandbox_url.rstrip('/')}/execute",
|
|
750
|
+
"timeout": int(os.environ.get("SANDBOX_TIMEOUT", "30")),
|
|
751
|
+
"connection_timeout": 5
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
@pytest.fixture(name="piston_url", scope="session")
|
|
756
|
+
def piston_url_fixture(fail_missing: bool) -> str:
|
|
757
|
+
"""
|
|
758
|
+
Configuration for piston testing.
|
|
759
|
+
|
|
760
|
+
The public piston server limits usage to five requests per minute.
|
|
761
|
+
"""
|
|
762
|
+
import requests
|
|
763
|
+
url = os.environ.get("NAT_CI_PISTON_URL", "https://emkc.org/api/v2/piston")
|
|
764
|
+
try:
|
|
765
|
+
response = requests.get(f"{url.rstrip('/')}/runtimes", timeout=30)
|
|
766
|
+
response.raise_for_status()
|
|
767
|
+
return url
|
|
768
|
+
except Exception:
|
|
769
|
+
reason = (f"Piston server is not running at {url}. "
|
|
770
|
+
"Please start it with: cd src/nat/tool/code_execution/local_sandbox && ./start_local_sandbox.sh")
|
|
771
|
+
if fail_missing:
|
|
772
|
+
raise RuntimeError(reason)
|
|
773
|
+
pytest.skip(reason)
|
nat/test/utils.py
CHANGED
|
@@ -73,14 +73,15 @@ async def run_workflow(*,
|
|
|
73
73
|
config_file: "StrPath | None" = None,
|
|
74
74
|
question: str,
|
|
75
75
|
expected_answer: str,
|
|
76
|
-
assert_expected_answer: bool = True
|
|
76
|
+
assert_expected_answer: bool = True,
|
|
77
|
+
**kwargs) -> str:
|
|
77
78
|
"""
|
|
78
79
|
Test specific wrapper for `nat.utils.run_workflow` to run a workflow with a question and validate the expected
|
|
79
80
|
answer. This variant always sets the result type to `str`.
|
|
80
81
|
"""
|
|
81
82
|
from nat.utils import run_workflow as nat_run_workflow
|
|
82
83
|
|
|
83
|
-
result = await nat_run_workflow(config=config, config_file=config_file, prompt=question, to_type=str)
|
|
84
|
+
result = await nat_run_workflow(config=config, config_file=config_file, prompt=question, to_type=str, **kwargs)
|
|
84
85
|
|
|
85
86
|
if assert_expected_answer:
|
|
86
87
|
assert expected_answer.lower() in result.lower(), f"Expected '{expected_answer}' in '{result}'"
|
{nvidia_nat_test-1.4.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.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.0a20251107
|
|
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.0a20251107
|
|
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.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.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=FxX-7bsIjY0cMKESEeMI47ZDICbhuWkEe1pUDJjR_GQ,28499
|
|
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=GyhxIZ1CcUPcc8RMRyCzpHBEwVifeqiGxT3c9Pp0KAU,5774
|
|
12
|
+
nvidia_nat_test-1.4.0a20251107.dist-info/licenses/LICENSE-3rd-party.txt,sha256=fOk5jMmCX9YoKWyYzTtfgl-SUy477audFC5hNY4oP7Q,284609
|
|
13
|
+
nvidia_nat_test-1.4.0a20251107.dist-info/licenses/LICENSE.md,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
|
14
|
+
nvidia_nat_test-1.4.0a20251107.dist-info/METADATA,sha256=jGHaCtfJVyngPdXauoWjyigY8ToGFP1RlVaOeBRTxqc,1925
|
|
15
|
+
nvidia_nat_test-1.4.0a20251107.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
+
nvidia_nat_test-1.4.0a20251107.dist-info/entry_points.txt,sha256=7dOP9XB6iMDqvav3gYx9VWUwA8RrFzhbAa8nGeC8e4Y,99
|
|
17
|
+
nvidia_nat_test-1.4.0a20251107.dist-info/top_level.txt,sha256=8-CJ2cP6-f0ZReXe5Hzqp-5pvzzHz-5Ds5H2bGqh1-U,4
|
|
18
|
+
nvidia_nat_test-1.4.0a20251107.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nvidia_nat_test-1.4.0a20251105.dist-info → nvidia_nat_test-1.4.0a20251107.dist-info}/top_level.txt
RENAMED
|
File without changes
|