참고소스 수정본

This commit is contained in:
LASTA_DEV01\lasta
2026-05-12 19:40:31 +09:00
parent 0f34a451fc
commit 2e9204243d
8708 changed files with 3259488 additions and 869 deletions

View File

@@ -0,0 +1,275 @@
import asyncio
import pytest
from time import sleep
from guardrails.validator_base import Validator, register_validator
from guardrails_ai.types import PassResult
@register_validator(name="test/validator1", data_type="string")
class Validator1(Validator):
def validate(self, value, metadata):
# This seems more realistic but is unreliable
# counter = 0
# for i in range(100000000):
# counter += 1
# This seems suspicious, but is consistent
sleep(0.3)
metadata["order"].append("test/validator1")
return PassResult()
@register_validator(name="test/validator2", data_type="string")
class Validator2(Validator):
def validate(self, value, metadata):
# counter = 0
# for i in range(1):
# counter += 1
sleep(0.1)
metadata["order"].append("test/validator2")
return PassResult()
@register_validator(name="test/validator3", data_type="string")
class Validator3(Validator):
def validate(self, value, metadata):
# counter = 0
# for i in range(100000):
# counter += 1
sleep(0.2)
metadata["order"].append("test/validator3")
return PassResult()
@register_validator(name="test/async_validator1", data_type="string")
class AsyncValidator1(Validator):
async def async_validate(self, value, metadata):
await asyncio.sleep(0.3)
metadata["order"].append("test/async_validator1")
return PassResult()
@register_validator(name="test/async_validator2", data_type="string")
class AsyncValidator2(Validator):
async def async_validate(self, value, metadata):
await asyncio.sleep(0.1)
metadata["order"].append("test/async_validator2")
return PassResult()
@register_validator(name="test/async_validator3", data_type="string")
class AsyncValidator3(Validator):
async def async_validate(self, value, metadata):
await asyncio.sleep(0.2)
metadata["order"].append("test/async_validator3")
return PassResult()
class TestValidatorConcurrency:
@pytest.mark.asyncio
async def test_async_validate_with_sync_validators(self):
from guardrails.validator_service import AsyncValidatorService
from guardrails.classes.history import Iteration
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
async_validator_service = AsyncValidatorService()
value, metadata = await async_validator_service.async_validate(
value="value",
metadata={"order": []},
validator_map={
"$": [
# Note the order
Validator1(),
Validator2(),
Validator3(),
]
},
iteration=iteration,
absolute_path="$",
reference_path="$",
)
assert value == "value"
assert metadata == {
"order": ["test/validator2", "test/validator3", "test/validator1"]
}
def test_validate_with_sync_validators(self):
from guardrails.validator_service import AsyncValidatorService
from guardrails.classes.history import Iteration
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
async_validator_service = AsyncValidatorService()
loop = asyncio.get_event_loop()
value, metadata = async_validator_service.validate(
value="value",
metadata={"order": []},
validator_map={
"$": [
# Note the order
Validator1(),
Validator2(),
Validator3(),
]
},
iteration=iteration,
absolute_path="$",
reference_path="$",
loop=loop,
)
assert value == "value"
assert metadata == {
"order": ["test/validator2", "test/validator3", "test/validator1"]
}
@pytest.mark.asyncio
async def test_async_validate_with_async_validators(self):
from guardrails.validator_service import AsyncValidatorService
from guardrails.classes.history import Iteration
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
async_validator_service = AsyncValidatorService()
value, metadata = await async_validator_service.async_validate(
value="value",
metadata={"order": []},
validator_map={
"$": [
# Note the order
AsyncValidator1(),
AsyncValidator2(),
AsyncValidator3(),
]
},
iteration=iteration,
absolute_path="$",
reference_path="$",
)
assert value == "value"
assert metadata == {
"order": [
"test/async_validator2",
"test/async_validator3",
"test/async_validator1",
]
}
def test_validate_with_async_validators(self):
from guardrails.validator_service import AsyncValidatorService
from guardrails.classes.history import Iteration
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
async_validator_service = AsyncValidatorService()
loop = asyncio.get_event_loop()
value, metadata = async_validator_service.validate(
value="value",
metadata={"order": []},
validator_map={
"$": [
# Note the order
AsyncValidator1(),
AsyncValidator2(),
AsyncValidator3(),
]
},
iteration=iteration,
absolute_path="$",
reference_path="$",
loop=loop,
)
assert value == "value"
assert metadata == {
"order": [
"test/async_validator2",
"test/async_validator3",
"test/async_validator1",
]
}
@pytest.mark.asyncio
async def test_async_validate_with_mixed_validators(self):
from guardrails.validator_service import AsyncValidatorService
from guardrails.classes.history import Iteration
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
async_validator_service = AsyncValidatorService()
value, metadata = await async_validator_service.async_validate(
value="value",
metadata={"order": []},
validator_map={
"$": [
# Note the order
Validator1(),
Validator2(),
AsyncValidator3(),
]
},
iteration=iteration,
absolute_path="$",
reference_path="$",
)
assert value == "value"
assert metadata == {
"order": ["test/validator2", "test/async_validator3", "test/validator1"]
}
def test_validate_with_mixed_validators(self):
from guardrails.validator_service import AsyncValidatorService
from guardrails.classes.history import Iteration
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
async_validator_service = AsyncValidatorService()
loop = asyncio.get_event_loop()
value, metadata = async_validator_service.validate(
value="value",
metadata={"order": []},
validator_map={
"$": [
# Note the order
Validator1(),
Validator2(),
AsyncValidator3(),
]
},
iteration=iteration,
absolute_path="$",
reference_path="$",
loop=loop,
)
assert value == "value"
assert metadata == {
"order": ["test/validator2", "test/async_validator3", "test/validator1"]
}

View File

@@ -0,0 +1,178 @@
from asyncio import get_event_loop
from asyncio.unix_events import _UnixSelectorEventLoop
import os
import pytest
from guardrails.validator_service import should_run_sync, get_loop
from guardrails.classes.history import Iteration
try:
import uvloop
except ImportError:
uvloop = None
class TestShouldRunSync:
def test_guardrails_run_sync_is_true(self):
GUARDRAILS_RUN_SYNC_bak = os.environ.get("GUARDRAILS_RUN_SYNC")
os.environ["GUARDRAILS_RUN_SYNC"] = "true"
result = should_run_sync()
assert result is True
if GUARDRAILS_RUN_SYNC_bak is not None:
os.environ["GUARDRAILS_RUN_SYNC"] = GUARDRAILS_RUN_SYNC_bak
else:
del os.environ["GUARDRAILS_RUN_SYNC"]
def test_guardrails_run_sync_is_false(self):
GUARDRAILS_RUN_SYNC_bak = os.environ.get("GUARDRAILS_RUN_SYNC")
os.environ["GUARDRAILS_RUN_SYNC"] = "false"
result = should_run_sync()
assert result is False
if GUARDRAILS_RUN_SYNC_bak is not None:
os.environ["GUARDRAILS_RUN_SYNC"] = GUARDRAILS_RUN_SYNC_bak
else:
del os.environ["GUARDRAILS_RUN_SYNC"]
class TestGetLoop:
def test_raises_if_loop_is_running(self):
loop = get_event_loop()
async def callback():
# NOTE: This means only AsyncGuard will parallelize validators
# if it's called within an async function.
with pytest.raises(RuntimeError, match="An event loop is already running."):
get_loop()
loop.run_until_complete(callback())
@pytest.mark.skipif(uvloop is None, reason="uvloop is not installed")
def test_uvloop_is_used_when_installed(self):
loop = get_loop()
assert isinstance(loop, uvloop.Loop)
@pytest.mark.skipif(uvloop is not None, reason="uvloop is installed")
def test_asyncio_default_is_used_otherwise(self):
loop = get_loop()
assert isinstance(loop, _UnixSelectorEventLoop)
class TestValidate:
def test_forced_sync(self, mocker):
GUARDRAILS_RUN_SYNC_bak = os.environ.get("GUARDRAILS_RUN_SYNC")
os.environ["GUARDRAILS_RUN_SYNC"] = "true"
from guardrails.validator_service import validate, SequentialValidatorService
mocker.spy(SequentialValidatorService, "__init__")
mocker.spy(SequentialValidatorService, "validate")
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
value, metadata = validate(
value="value",
metadata={},
validator_map={},
iteration=iteration,
)
assert value == "value"
assert metadata == {}
SequentialValidatorService.__init__.assert_called_once()
SequentialValidatorService.validate.assert_called_once()
if GUARDRAILS_RUN_SYNC_bak is not None:
os.environ["GUARDRAILS_RUN_SYNC"] = GUARDRAILS_RUN_SYNC_bak
else:
del os.environ["GUARDRAILS_RUN_SYNC"]
def test_async(self, mocker):
from guardrails.validator_service import validate, AsyncValidatorService
mocker.spy(AsyncValidatorService, "__init__")
mocker.spy(AsyncValidatorService, "validate")
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
value, metadata = validate(
value="value",
metadata={},
validator_map={},
iteration=iteration,
)
assert value == "value"
assert metadata == {}
AsyncValidatorService.__init__.assert_called_once()
AsyncValidatorService.validate.assert_called_once()
def test_sync_busy_loop(self, mocker):
from guardrails.validator_service import validate, SequentialValidatorService
mocker.spy(SequentialValidatorService, "__init__")
mocker.spy(SequentialValidatorService, "validate")
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
loop = get_event_loop()
async def callback():
with pytest.warns(
Warning,
match=(
"Could not obtain an event loop."
" Falling back to synchronous validation."
),
):
value, metadata = validate(
value="value",
metadata={},
validator_map={},
iteration=iteration,
)
assert value == "value"
assert metadata == {}
loop.run_until_complete(callback())
SequentialValidatorService.__init__.assert_called_once()
SequentialValidatorService.validate.assert_called_once()
@pytest.mark.asyncio
async def test_async_validate(mocker):
from guardrails.validator_service import async_validate, AsyncValidatorService
mocker.spy(AsyncValidatorService, "__init__")
mocker.spy(AsyncValidatorService, "async_validate")
iteration = Iteration(
call_id="mock_call_id",
index=0,
)
value, metadata = await async_validate(
value="value",
metadata={},
validator_map={},
iteration=iteration,
)
assert value == "value"
assert metadata == {}
AsyncValidatorService.__init__.assert_called_once()
AsyncValidatorService.async_validate.assert_called_once()