Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GET history endpoint #50

Merged
merged 6 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ install:

# Installs development dependencies
install-dev:
pip install .[dev];
pip install ".[dev]";

lock:
pip freeze --exclude guardrails-api-client > requirements-lock.txt
Expand Down
4 changes: 4 additions & 0 deletions guardrails_api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from guardrails_api.clients.postgres_client import postgres_is_enabled
from guardrails_api.otel import otel_is_disabled, initialize
from guardrails_api.clients.cache_client import CacheClient


# TODO: Move this to a separate file
Expand Down Expand Up @@ -80,6 +81,9 @@ def create_app(env: Optional[str] = None, config: Optional[str] = None):

pg_client = PostgresClient()
pg_client.initialize(app)

cache_client = CacheClient()
cache_client.initialize(app)

from guardrails_api.blueprints.root import root_bp
from guardrails_api.blueprints.guards import guards_bp
Expand Down
15 changes: 15 additions & 0 deletions guardrails_api/blueprints/guards.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from opentelemetry.trace import Span
from guardrails_api_client import Guard as GuardStruct
from guardrails_api.classes.http_error import HttpError
from guardrails_api.clients.cache_client import CacheClient
from guardrails_api.clients.memory_guard_client import MemoryGuardClient
from guardrails_api.clients.pg_guard_client import PGGuardClient
from guardrails_api.clients.postgres_client import postgres_is_enabled
Expand All @@ -34,6 +35,8 @@
is_guard = isinstance(export, Guard)
if is_guard:
guard_client.create_guard(export)

cache_client = CacheClient()


@guards_bp.route("/", methods=["GET", "POST"])
Expand Down Expand Up @@ -308,4 +311,16 @@ def validate_streamer(guard_iter):
# prompt_params=prompt_params,
# result=result
# )
serialized_history = [
call.to_dict() for call in guard.history
]
cache_key = f"{guard.name}-{result.call_id}"
cache_client.set(cache_key, serialized_history, 300)
return result.to_dict()

@guards_bp.route("/<guard_name>/history/<call_id>", methods=["GET"])
@handle_error
def guard_history(guard_name: str, call_id: str):
if request.method == "GET":
cache_key = f"{guard_name}-{call_id}"
return cache_client.get(cache_key)
35 changes: 35 additions & 0 deletions guardrails_api/clients/cache_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from flask_caching import Cache


# TODO: Add option to connect to Redis or MemCached backend with environment variables
class CacheClient:
_instance = None

def __new__(cls):
if cls._instance is None:
cls._instance = super(CacheClient, cls).__new__(cls)
return cls._instance


def initialize(self, app):
self.cache = Cache(
app,
config={
"CACHE_TYPE": "simple",
"CACHE_DEFAULT_TIMEOUT": 300,
"CACHE_NO_NULL_WARNING": True,
"CACHE_THRESHOLD": 50
}
)

def get(self, key):
return self.cache.get(key)

def set(self, key, value, ttl):
self.cache.set(key, value, timeout=ttl)

def delete(self, key):
self.cache.delete(key)

def clear(self):
self.cache.clear()
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ readme = "README.md"
keywords = ["Guardrails", "Guardrails AI", "Guardrails API", "Guardrails API"]
requires-python = ">= 3.8.1"
dependencies = [
"guardrails-ai@git+https://github.com/guardrails-ai/guardrails.git@core-schema-impl",
"guardrails-ai@git+https://github.com/guardrails-ai/guardrails.git@0.5.0-dev",
"flask>=3.0.3,<4",
"Flask-SQLAlchemy>=3.1.1,<4",
"Flask-Caching>=2.3.0,<3",
"Werkzeug>=3.0.3,<4",
"jsonschema>=4.22.0,<5",
"referencing>=0.35.1,<1",
Expand Down
Loading