langchain/tests/unit_tests/tools/openapi/test_api_models.py
Harrison Chase 26314d7004
Harrison/openapi parser (#2461)
Co-authored-by: William FH <13333726+hinthornw@users.noreply.github.com>
2023-04-05 22:19:09 -07:00

76 lines
2.3 KiB
Python

"""Test the APIOperation class."""
import json
import os
from pathlib import Path
from typing import Iterable, List, Tuple
import pytest
import yaml
from langchain.tools.openapi.utils.api_models import APIOperation
from langchain.tools.openapi.utils.openapi_utils import HTTPVerb, OpenAPISpec
_DIR = Path(__file__).parent
def _get_test_specs() -> Iterable[Path]:
"""Walk the test_specs directory and collect all files with the name 'apispec'
in them.
"""
test_specs_dir = _DIR / "test_specs"
return (
Path(root) / file
for root, _, files in os.walk(test_specs_dir)
for file in files
if file.startswith("apispec")
)
def _get_paths_and_methods_from_spec_dictionary(
spec: dict,
) -> Iterable[Tuple[str, str]]:
"""Return a tuple (paths, methods) for every path in spec."""
valid_methods = [verb.value for verb in HTTPVerb]
for path_name, path_item in spec["paths"].items():
for method in valid_methods:
if method in path_item:
yield (path_name, method)
def http_paths_and_methods() -> List[Tuple[str, OpenAPISpec, str, str]]:
"""Return a args for every method in cached OpenAPI spec in test_specs."""
http_paths_and_methods = []
for test_spec in _get_test_specs():
spec_name = test_spec.parent.name
if test_spec.suffix == ".json":
with test_spec.open("r") as f:
spec = json.load(f)
else:
with test_spec.open("r") as f:
spec = yaml.safe_load(f.read())
parsed_spec = OpenAPISpec.from_file(test_spec)
for path, method in _get_paths_and_methods_from_spec_dictionary(spec):
http_paths_and_methods.append(
(
spec_name,
parsed_spec,
path,
method,
)
)
return http_paths_and_methods
@pytest.mark.parametrize(
"spec_name, spec, path, method",
http_paths_and_methods(),
)
def test_parse_api_operations(
spec_name: str, spec: OpenAPISpec, path: str, method: str
) -> None:
"""Test the APIOperation class."""
try:
APIOperation.from_openapi_spec(spec, path, method)
except Exception as e:
raise AssertionError(f"Error processong {spec_name}: {e} ") from e