Skip to content

[bug] AsyncGuard fails to await when called remotely #1149

@NWalker4483

Description

@NWalker4483

Describe the bug
I'm unable to appropriately call an async guard on my server. When I define it as a regular guard it works, local and over the server. Also, if I define an async guard locally and await as I do in my app code that is attempting to use the server, it works.

guardrails-1     | /opt/venv/lib/python3.11/site-packages/guardrails_api/utils/handle_error.py:30: RuntimeWarning: coroutine 'AsyncGuard.parse' was never awaited
guardrails-1     |   return HttpError(500, "Internal Server Error").to_dict(), 500
guardrails-1     | RuntimeWarning: Enable tracemalloc to get the object allocation traceback
guardrails-1     | ERROR:guardrails-api:'coroutine' object has no attribute 'call_id'
guardrails-1     | Traceback (most recent call last):
guardrails-1     |   File "/opt/venv/lib/python3.11/site-packages/guardrails_api/utils/handle_error.py", line 13, in decorator
guardrails-1     |     return fn(*args, **kwargs)
guardrails-1     |            ^^^^^^^^^^^^^^^^^^^
guardrails-1     |   File "/opt/venv/lib/python3.11/site-packages/guardrails_api/blueprints/guards.py", line 497, in validate
guardrails-1     |     cache_key = f"{guard.name}-{result.call_id}"
guardrails-1     |                                 ^^^^^^^^^^^^^^
guardrails-1     | AttributeError: 'coroutine' object has no attribute 'call_id'

To Reproduce
config.py in guardrails-lite-server/

from guardrails import AsyncGuard, Guard
from guardrails.hub import DetectPII, ToxicLanguage, ValidLength
# Custom Long Validators I tested without 
# Create the combined guard
valid_question = (
    AsyncGuard(name="valid_question")
    .use(ValidLength, min=10, max=300, on_fail="noop")
    .use(ToxicLanguage, threshold=0.5, validation_method="sentence", on_fail="noop")
    .use(DetectPII, ["EMAIL_ADDRESS", "PHONE_NUMBER"], on_fail="noop")

my app code

import guardrails as gr

gr.settings.use_server = True
question="Something "
valid_question = gr.AsyncGuard(name='valid_question')
result = await valid_question.validate(question, metadata={})
print(f"Validation passed: {result.validation_passed}")
print(result)
if not result.validation_passed:
    if result.reask:
        print("Validation errors (reask):")
        for fail_result in result.reask.fail_results:
            print(f"- {fail_result.error_message}")
    else:
        print("Validation filtered or refrained")

Expected behavior
I would expect that I would need to define an async guard on my client and server in order for validators to run asynchronously. Or I would even understand if I needed to define an async guard on the server and then just a regular guard on the client. Which doesn't call the validators. But this is a server-side error.

Library version:
Version 0.5.15

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions