nvidia-nat-test 1.1.0a20251020__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 ADDED
@@ -0,0 +1,592 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import os
17
+ import subprocess
18
+ import time
19
+ import types
20
+ import typing
21
+ from collections.abc import AsyncGenerator
22
+ from collections.abc import Generator
23
+ from pathlib import Path
24
+
25
+ import pytest
26
+ import pytest_asyncio
27
+
28
+ if typing.TYPE_CHECKING:
29
+ from docker.client import DockerClient
30
+
31
+
32
+ def pytest_addoption(parser: pytest.Parser):
33
+ """
34
+ Adds command line options for running specfic tests that are disabled by default
35
+ """
36
+ parser.addoption(
37
+ "--run_integration",
38
+ action="store_true",
39
+ dest="run_integration",
40
+ help=("Run integrations tests that would otherwise be skipped. "
41
+ "This will call out to external services instead of using mocks"),
42
+ )
43
+
44
+ parser.addoption(
45
+ "--run_slow",
46
+ action="store_true",
47
+ dest="run_slow",
48
+ help="Run end to end tests that would otherwise be skipped",
49
+ )
50
+
51
+ parser.addoption(
52
+ "--fail_missing",
53
+ action="store_true",
54
+ dest="fail_missing",
55
+ help=("Tests requiring unmet dependencies are normally skipped. "
56
+ "Setting this flag will instead cause them to be reported as a failure"),
57
+ )
58
+
59
+
60
+ def pytest_runtest_setup(item):
61
+ if (not item.config.getoption("--run_integration")):
62
+ if (item.get_closest_marker("integration") is not None):
63
+ pytest.skip("Skipping integration tests by default. Use --run_integration to enable")
64
+
65
+ if (not item.config.getoption("--run_slow")):
66
+ if (item.get_closest_marker("slow") is not None):
67
+ pytest.skip("Skipping slow tests by default. Use --run_slow to enable")
68
+
69
+
70
+ @pytest.fixture(name="register_components", scope="session", autouse=True)
71
+ def register_components_fixture():
72
+ from nat.runtime.loader import PluginTypes
73
+ from nat.runtime.loader import discover_and_register_plugins
74
+
75
+ # Ensure that all components which need to be registered as part of an import are done so. This is necessary
76
+ # because imports will not be reloaded between tests, so we need to ensure that all components are registered
77
+ # before any tests are run.
78
+ discover_and_register_plugins(PluginTypes.ALL)
79
+
80
+ # Also import the nat.test.register module to register test-only components
81
+
82
+
83
+ @pytest.fixture(name="module_registry", scope="module", autouse=True)
84
+ def module_registry_fixture():
85
+ """
86
+ Resets and returns the global type registry for testing
87
+
88
+ This gets automatically used at the module level to ensure no state is leaked between modules
89
+ """
90
+ from nat.cli.type_registry import GlobalTypeRegistry
91
+
92
+ with GlobalTypeRegistry.push() as registry:
93
+ yield registry
94
+
95
+
96
+ @pytest.fixture(name="registry", scope="function", autouse=True)
97
+ def function_registry_fixture():
98
+ """
99
+ Resets and returns the global type registry for testing
100
+
101
+ This gets automatically used at the function level to ensure no state is leaked between functions
102
+ """
103
+ from nat.cli.type_registry import GlobalTypeRegistry
104
+
105
+ with GlobalTypeRegistry.push() as registry:
106
+ yield registry
107
+
108
+
109
+ @pytest.fixture(scope="session", name="fail_missing")
110
+ def fail_missing_fixture(pytestconfig: pytest.Config) -> bool:
111
+ """
112
+ Returns the value of the `fail_missing` flag, when false tests requiring unmet dependencies will be skipped, when
113
+ True they will fail.
114
+ """
115
+ yield pytestconfig.getoption("fail_missing")
116
+
117
+
118
+ def require_env_variables(varnames: list[str], reason: str, fail_missing: bool = False) -> dict[str, str]:
119
+ """
120
+ Checks if the given environment variable is set, and returns its value if it is. If the variable is not set, and
121
+ `fail_missing` is False the test will ve skipped, otherwise a `RuntimeError` will be raised.
122
+ """
123
+ env_variables = {}
124
+ try:
125
+ for varname in varnames:
126
+ env_variables[varname] = os.environ[varname]
127
+ except KeyError as e:
128
+ if fail_missing:
129
+ raise RuntimeError(reason) from e
130
+
131
+ pytest.skip(reason=reason)
132
+
133
+ return env_variables
134
+
135
+
136
+ @pytest.fixture(name="openai_api_key", scope='session')
137
+ def openai_api_key_fixture(fail_missing: bool):
138
+ """
139
+ Use for integration tests that require an Openai API key.
140
+ """
141
+ yield require_env_variables(
142
+ varnames=["OPENAI_API_KEY"],
143
+ reason="openai integration tests require the `OPENAI_API_KEY` environment variable to be defined.",
144
+ fail_missing=fail_missing)
145
+
146
+
147
+ @pytest.fixture(name="nvidia_api_key", scope='session')
148
+ def nvidia_api_key_fixture(fail_missing: bool):
149
+ """
150
+ Use for integration tests that require an Nvidia API key.
151
+ """
152
+ yield require_env_variables(
153
+ varnames=["NVIDIA_API_KEY"],
154
+ reason="Nvidia integration tests require the `NVIDIA_API_KEY` environment variable to be defined.",
155
+ fail_missing=fail_missing)
156
+
157
+
158
+ @pytest.fixture(name="serp_api_key", scope='session')
159
+ def serp_api_key_fixture(fail_missing: bool):
160
+ """
161
+ Use for integration tests that require a SERP API (serpapi.com) key.
162
+ """
163
+ yield require_env_variables(
164
+ varnames=["SERP_API_KEY"],
165
+ reason="SERP integration tests require the `SERP_API_KEY` environment variable to be defined.",
166
+ fail_missing=fail_missing)
167
+
168
+
169
+ @pytest.fixture(name="serperdev", scope='session')
170
+ def serperdev_api_key_fixture(fail_missing: bool):
171
+ """
172
+ Use for integration tests that require a Serper Dev API (https://serper.dev) key.
173
+ """
174
+ yield require_env_variables(
175
+ varnames=["SERPERDEV_API_KEY"],
176
+ reason="SERPERDEV integration tests require the `SERPERDEV_API_KEY` environment variable to be defined.",
177
+ fail_missing=fail_missing)
178
+
179
+
180
+ @pytest.fixture(name="tavily_api_key", scope='session')
181
+ def tavily_api_key_fixture(fail_missing: bool):
182
+ """
183
+ Use for integration tests that require a Tavily API key.
184
+ """
185
+ yield require_env_variables(
186
+ varnames=["TAVILY_API_KEY"],
187
+ reason="Tavily integration tests require the `TAVILY_API_KEY` environment variable to be defined.",
188
+ fail_missing=fail_missing)
189
+
190
+
191
+ @pytest.fixture(name="mem0_api_key", scope='session')
192
+ def mem0_api_key_fixture(fail_missing: bool):
193
+ """
194
+ Use for integration tests that require a Mem0 API key.
195
+ """
196
+ yield require_env_variables(
197
+ varnames=["MEM0_API_KEY"],
198
+ reason="Mem0 integration tests require the `MEM0_API_KEY` environment variable to be defined.",
199
+ fail_missing=fail_missing)
200
+
201
+
202
+ @pytest.fixture(name="aws_keys", scope='session')
203
+ def aws_keys_fixture(fail_missing: bool):
204
+ """
205
+ Use for integration tests that require AWS credentials.
206
+ """
207
+
208
+ yield require_env_variables(
209
+ varnames=["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"],
210
+ reason=
211
+ "AWS integration tests require the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables to be "
212
+ "defined.",
213
+ fail_missing=fail_missing)
214
+
215
+
216
+ @pytest.fixture(name="azure_openai_keys", scope='session')
217
+ def azure_openai_keys_fixture(fail_missing: bool):
218
+ """
219
+ Use for integration tests that require Azure OpenAI credentials.
220
+ """
221
+ yield require_env_variables(
222
+ varnames=["AZURE_OPENAI_API_KEY", "AZURE_OPENAI_ENDPOINT"],
223
+ reason="Azure integration tests require the `AZURE_OPENAI_API_KEY` and `AZURE_OPENAI_ENDPOINT` environment "
224
+ "variables to be defined.",
225
+ fail_missing=fail_missing)
226
+
227
+
228
+ @pytest.fixture(name="langfuse_keys", scope='session')
229
+ def langfuse_keys_fixture(fail_missing: bool):
230
+ """
231
+ Use for integration tests that require Langfuse credentials.
232
+ """
233
+ yield require_env_variables(
234
+ varnames=["LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY"],
235
+ reason="Langfuse integration tests require the `LANGFUSE_PUBLIC_KEY` and `LANGFUSE_SECRET_KEY` environment "
236
+ "variables to be defined.",
237
+ fail_missing=fail_missing)
238
+
239
+
240
+ @pytest.fixture(name="wandb_api_key", scope='session')
241
+ def wandb_api_key_fixture(fail_missing: bool):
242
+ """
243
+ Use for integration tests that require a Weights & Biases API key.
244
+ """
245
+ yield require_env_variables(
246
+ varnames=["WANDB_API_KEY"],
247
+ reason="Weights & Biases integration tests require the `WANDB_API_KEY` environment variable to be defined.",
248
+ fail_missing=fail_missing)
249
+
250
+
251
+ @pytest.fixture(name="weave", scope='session')
252
+ def require_weave_fixture(fail_missing: bool) -> types.ModuleType:
253
+ """
254
+ Use for integration tests that require Weave to be running.
255
+ """
256
+ try:
257
+ import weave
258
+ return weave
259
+ except Exception as e:
260
+ reason = "Weave must be installed to run weave based tests"
261
+ if fail_missing:
262
+ raise RuntimeError(reason) from e
263
+ pytest.skip(reason=reason)
264
+
265
+
266
+ @pytest.fixture(name="require_docker", scope='session')
267
+ def require_docker_fixture(fail_missing: bool) -> "DockerClient":
268
+ """
269
+ Use for integration tests that require Docker to be running.
270
+ """
271
+ try:
272
+ from docker.client import DockerClient
273
+ yield DockerClient()
274
+ except Exception as e:
275
+ reason = f"Unable to connect to Docker daemon: {e}"
276
+ if fail_missing:
277
+ raise RuntimeError(reason) from e
278
+ pytest.skip(reason=reason)
279
+
280
+
281
+ @pytest.fixture(name="restore_environ")
282
+ def restore_environ_fixture():
283
+ orig_vars = os.environ.copy()
284
+ yield os.environ
285
+
286
+ for key, value in orig_vars.items():
287
+ os.environ[key] = value
288
+
289
+ # Delete any new environment variables
290
+ # Iterating over a copy of the keys as we will potentially be deleting keys in the loop
291
+ for key in list(os.environ.keys()):
292
+ if key not in orig_vars:
293
+ del (os.environ[key])
294
+
295
+
296
+ @pytest.fixture(name="root_repo_dir", scope='session')
297
+ def root_repo_dir_fixture() -> Path:
298
+ from nat.test.utils import locate_repo_root
299
+ return locate_repo_root()
300
+
301
+
302
+ @pytest.fixture(name="examples_dir", scope='session')
303
+ def examples_dir_fixture(root_repo_dir: Path) -> Path:
304
+ return root_repo_dir / "examples"
305
+
306
+
307
+ @pytest.fixture(name="require_etcd", scope="session")
308
+ def require_etcd_fixture(fail_missing: bool = False) -> bool:
309
+ """
310
+ To run these tests, an etcd server must be running
311
+ """
312
+ import requests
313
+
314
+ host = os.getenv("NAT_CI_ETCD_HOST", "localhost")
315
+ port = os.getenv("NAT_CI_ETCD_PORT", "2379")
316
+ health_url = f"http://{host}:{port}/health"
317
+
318
+ try:
319
+ response = requests.get(health_url, timeout=5)
320
+ response.raise_for_status()
321
+ return True
322
+ except: # noqa: E722
323
+ failure_reason = f"Unable to connect to etcd server at {health_url}"
324
+ if fail_missing:
325
+ raise RuntimeError(failure_reason)
326
+ pytest.skip(reason=failure_reason)
327
+
328
+
329
+ @pytest.fixture(name="milvus_uri", scope="session")
330
+ def milvus_uri_fixture(require_etcd: bool, fail_missing: bool = False) -> str:
331
+ """
332
+ To run these tests, a Milvus server must be running
333
+ """
334
+ host = os.getenv("NAT_CI_MILVUS_HOST", "localhost")
335
+ port = os.getenv("NAT_CI_MILVUS_PORT", "19530")
336
+ uri = f"http://{host}:{port}"
337
+ try:
338
+ from pymilvus import MilvusClient
339
+ MilvusClient(uri=uri)
340
+
341
+ return uri
342
+ except: # noqa: E722
343
+ reason = f"Unable to connect to Milvus server at {uri}"
344
+ if fail_missing:
345
+ raise RuntimeError(reason)
346
+ pytest.skip(reason=reason)
347
+
348
+
349
+ @pytest.fixture(name="populate_milvus", scope="session")
350
+ def populate_milvus_fixture(milvus_uri: str, root_repo_dir: Path):
351
+ """
352
+ Populate Milvus with some test data.
353
+ """
354
+ populate_script = root_repo_dir / "scripts/langchain_web_ingest.py"
355
+
356
+ # Ingest default cuda docs
357
+ subprocess.run(["python", str(populate_script), "--milvus_uri", milvus_uri], check=True)
358
+
359
+ # Ingest MCP docs
360
+ subprocess.run([
361
+ "python",
362
+ str(populate_script),
363
+ "--milvus_uri",
364
+ milvus_uri,
365
+ "--urls",
366
+ "https://github.com/modelcontextprotocol/python-sdk",
367
+ "--urls",
368
+ "https://modelcontextprotocol.io/introduction",
369
+ "--urls",
370
+ "https://modelcontextprotocol.io/quickstart/server",
371
+ "--urls",
372
+ "https://modelcontextprotocol.io/quickstart/client",
373
+ "--urls",
374
+ "https://modelcontextprotocol.io/examples",
375
+ "--urls",
376
+ "https://modelcontextprotocol.io/docs/concepts/architecture",
377
+ "--collection_name",
378
+ "mcp_docs"
379
+ ],
380
+ check=True)
381
+
382
+ # Ingest some wikipedia docs
383
+ subprocess.run([
384
+ "python",
385
+ str(populate_script),
386
+ "--milvus_uri",
387
+ milvus_uri,
388
+ "--urls",
389
+ "https://en.wikipedia.org/wiki/Aardvark",
390
+ "--collection_name",
391
+ "wikipedia_docs"
392
+ ],
393
+ check=True)
394
+
395
+
396
+ @pytest.fixture(name="require_nest_asyncio", scope="session")
397
+ def require_nest_asyncio_fixture():
398
+ """
399
+ Some tests require nest_asyncio to be installed to allow nested event loops, calling nest_asyncio.apply() more than
400
+ once is a no-op so it's safe to call this fixture even if one of our dependencies already called it.
401
+ """
402
+ import nest_asyncio
403
+ nest_asyncio.apply()
404
+
405
+
406
+ @pytest.fixture(name="phoenix_url", scope="session")
407
+ def phoenix_url_fixture(fail_missing: bool) -> str:
408
+ """
409
+ To run these tests, a phoenix server must be running.
410
+ The phoenix server can be started by running the following command:
411
+ docker run -p 6006:6006 -p 4317:4317 arizephoenix/phoenix:latest
412
+ """
413
+ import requests
414
+
415
+ url = os.getenv("NAT_CI_PHOENIX_URL", "http://localhost:6006")
416
+ try:
417
+ response = requests.get(url, timeout=5)
418
+ response.raise_for_status()
419
+
420
+ return url
421
+ except Exception as e:
422
+ reason = f"Unable to connect to Phoenix server at {url}: {e}"
423
+ if fail_missing:
424
+ raise RuntimeError(reason)
425
+ pytest.skip(reason=reason)
426
+
427
+
428
+ @pytest.fixture(name="phoenix_trace_url", scope="session")
429
+ def phoenix_trace_url_fixture(phoenix_url: str) -> str:
430
+ """
431
+ Some of our tools expect the base url provided by the phoenix_url fixture, however the
432
+ general.telemetry.tracing["phoenix"].endpoint expects the trace url which is what this fixture provides.
433
+ """
434
+ return f"{phoenix_url}/v1/traces"
435
+
436
+
437
+ @pytest.fixture(name="redis_server", scope="session")
438
+ def fixture_redis_server(fail_missing: bool) -> Generator[dict[str, str | int]]:
439
+ """Fixture to safely skip redis based tests if redis is not running"""
440
+ host = os.environ.get("NAT_CI_REDIS_HOST", "localhost")
441
+ port = int(os.environ.get("NAT_CI_REDIS_PORT", "6379"))
442
+ db = int(os.environ.get("NAT_CI_REDIS_DB", "0"))
443
+ bucket_name = os.environ.get("NAT_CI_REDIS_BUCKET_NAME", "test")
444
+
445
+ try:
446
+ import redis
447
+ client = redis.Redis(host=host, port=port, db=db)
448
+ if not client.ping():
449
+ raise RuntimeError("Failed to connect to Redis")
450
+ yield {"host": host, "port": port, "db": db, "bucket_name": bucket_name}
451
+ except ImportError:
452
+ if fail_missing:
453
+ raise
454
+ pytest.skip("redis not installed, skipping redis tests")
455
+ except Exception as e:
456
+ if fail_missing:
457
+ raise
458
+ pytest.skip(f"Error connecting to Redis server: {e}, skipping redis tests")
459
+
460
+
461
+ @pytest_asyncio.fixture(name="mysql_server", scope="session")
462
+ async def fixture_mysql_server(fail_missing: bool) -> AsyncGenerator[dict[str, str | int]]:
463
+ """Fixture to safely skip MySQL based tests if MySQL is not running"""
464
+ host = os.environ.get('NAT_CI_MYSQL_HOST', '127.0.0.1')
465
+ port = int(os.environ.get('NAT_CI_MYSQL_PORT', '3306'))
466
+ user = os.environ.get('NAT_CI_MYSQL_USER', 'root')
467
+ password = os.environ.get('MYSQL_ROOT_PASSWORD', 'my_password')
468
+ bucket_name = os.environ.get('NAT_CI_MYSQL_BUCKET_NAME', 'test')
469
+ try:
470
+ import aiomysql
471
+ conn = await aiomysql.connect(host=host, port=port, user=user, password=password)
472
+ yield {"host": host, "port": port, "username": user, "password": password, "bucket_name": bucket_name}
473
+ conn.close()
474
+ except ImportError:
475
+ if fail_missing:
476
+ raise
477
+ pytest.skip("aiomysql not installed, skipping MySQL tests")
478
+ except Exception as e:
479
+ if fail_missing:
480
+ raise
481
+ pytest.skip(f"Error connecting to MySQL server: {e}, skipping MySQL tests")
482
+
483
+
484
+ @pytest.fixture(name="minio_server", scope="session")
485
+ def minio_server_fixture(fail_missing: bool) -> Generator[dict[str, str | int]]:
486
+ """Fixture to safely skip MinIO based tests if MinIO is not running"""
487
+ host = os.getenv("NAT_CI_MINIO_HOST", "localhost")
488
+ port = int(os.getenv("NAT_CI_MINIO_PORT", "9000"))
489
+ bucket_name = os.getenv("NAT_CI_MINIO_BUCKET_NAME", "test")
490
+ aws_access_key_id = os.getenv("NAT_CI_MINIO_ACCESS_KEY_ID", "minioadmin")
491
+ aws_secret_access_key = os.getenv("NAT_CI_MINIO_SECRET_ACCESS_KEY", "minioadmin")
492
+ endpoint_url = f"http://{host}:{port}"
493
+
494
+ minio_info = {
495
+ "host": host,
496
+ "port": port,
497
+ "bucket_name": bucket_name,
498
+ "endpoint_url": endpoint_url,
499
+ "aws_access_key_id": aws_access_key_id,
500
+ "aws_secret_access_key": aws_secret_access_key,
501
+ }
502
+
503
+ try:
504
+ import botocore.session
505
+ session = botocore.session.get_session()
506
+
507
+ client = session.create_client("s3",
508
+ aws_access_key_id=aws_access_key_id,
509
+ aws_secret_access_key=aws_secret_access_key,
510
+ endpoint_url=endpoint_url)
511
+ client.list_buckets()
512
+ yield minio_info
513
+ except ImportError:
514
+ if fail_missing:
515
+ raise
516
+ pytest.skip("aioboto3 not installed, skipping MinIO tests")
517
+ except Exception as e:
518
+ if fail_missing:
519
+ raise
520
+ else:
521
+ pytest.skip(f"Error connecting to MinIO server: {e}, skipping MinIO tests")
522
+
523
+
524
+ @pytest.fixture(name="langfuse_bucket", scope="session")
525
+ def langfuse_bucket_fixture(fail_missing: bool, minio_server: dict[str, str | int]) -> Generator[str]:
526
+
527
+ bucket_name = os.getenv("NAT_CI_LANGFUSE_BUCKET", "langfuse")
528
+ try:
529
+ import botocore.session
530
+ session = botocore.session.get_session()
531
+
532
+ client = session.create_client("s3",
533
+ aws_access_key_id=minio_server["aws_access_key_id"],
534
+ aws_secret_access_key=minio_server["aws_secret_access_key"],
535
+ endpoint_url=minio_server["endpoint_url"])
536
+
537
+ buckets = client.list_buckets()
538
+ bucket_names = [b['Name'] for b in buckets['Buckets']]
539
+ if bucket_name not in bucket_names:
540
+ client.create_bucket(Bucket=bucket_name)
541
+
542
+ yield bucket_name
543
+ except ImportError:
544
+ if fail_missing:
545
+ raise
546
+ pytest.skip("aioboto3 not installed, skipping MinIO tests")
547
+ except Exception as e:
548
+ if fail_missing:
549
+ raise
550
+ else:
551
+ pytest.skip(f"Error connecting to MinIO server: {e}, skipping MinIO tests")
552
+
553
+
554
+ @pytest.fixture(name="langfuse_url", scope="session")
555
+ def langfuse_url_fixture(fail_missing: bool, langfuse_bucket: str) -> str:
556
+ """
557
+ To run these tests, a langfuse server must be running.
558
+ """
559
+ import requests
560
+
561
+ host = os.getenv("NAT_CI_LANGFUSE_HOST", "localhost")
562
+ port = int(os.getenv("NAT_CI_LANGFUSE_PORT", "3000"))
563
+ url = f"http://{host}:{port}"
564
+ health_endpoint = f"{url}/api/public/health"
565
+ try:
566
+ max_tries = 5
567
+ for attempt in range(max_tries):
568
+ try:
569
+ response = requests.get(health_endpoint, timeout=30)
570
+ print(f"Langfuse health check response ({attempt}): {health_endpoint} - {response.text}")
571
+ response.raise_for_status()
572
+ return url
573
+ except Exception as e:
574
+ if attempt < max_tries - 1:
575
+ time.sleep(10)
576
+ else:
577
+ raise RuntimeError(f"Max retries ({max_tries}) exceeded") from e
578
+
579
+ except Exception as e:
580
+ reason = f"Unable to connect to Langfuse server at {url}: {e}"
581
+ if fail_missing:
582
+ raise RuntimeError(reason)
583
+ pytest.skip(reason=reason)
584
+
585
+
586
+ @pytest.fixture(name="langfuse_trace_url", scope="session")
587
+ def langfuse_trace_url_fixture(langfuse_url: str) -> str:
588
+ """
589
+ The langfuse_url fixture provides the base url, however the general.telemetry.tracing["langfuse"].endpoint expects
590
+ the trace url which is what this fixture provides.
591
+ """
592
+ return f"{langfuse_url}/api/public/otel/v1/traces"
nat/test/register.py ADDED
@@ -0,0 +1,25 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # flake8: noqa
17
+ # isort:skip_file
18
+
19
+ # Import any providers which need to be automatically registered here
20
+
21
+ from . import embedder
22
+ from . import functions
23
+ from . import memory
24
+ from . import llm
25
+ from . import utils