-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into feature/truncate-function
- Loading branch information
Showing
26 changed files
with
923 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from fastapi import APIRouter, Depends | ||
|
||
from app.dependencies import TokenValidator | ||
from app.models.dtos import LLMStatus, ModelStatus | ||
from app.services.guidance_wrapper import GuidanceWrapper | ||
from app.services.circuit_breaker import CircuitBreaker | ||
from app.config import settings | ||
|
||
router = APIRouter() | ||
|
||
|
||
@router.get("/api/v1/health", dependencies=[Depends(TokenValidator())]) | ||
def checkhealth() -> list[ModelStatus]: | ||
result = [] | ||
|
||
for key, model in settings.pyris.llms.items(): | ||
circuit_status = CircuitBreaker.get_status( | ||
checkhealth_func=GuidanceWrapper(model=model).is_up, | ||
cache_key=key, | ||
) | ||
status = ( | ||
LLMStatus.UP | ||
if circuit_status == CircuitBreaker.Status.CLOSED | ||
else LLMStatus.DOWN | ||
) | ||
result.append(ModelStatus(model=key, status=status)) | ||
|
||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
from abc import ABC, abstractmethod | ||
from datetime import datetime, timedelta | ||
from typing import Optional, Any | ||
from pydantic import BaseModel | ||
from app.services.hazelcast_client import hazelcast_client | ||
|
||
|
||
class CacheStoreInterface(ABC): | ||
@abstractmethod | ||
def get(self, name: str) -> Any: | ||
""" | ||
Get the value at key ``name`` | ||
Returns: | ||
The value at key ``name``, or None if the key doesn't exist | ||
""" | ||
pass | ||
|
||
@abstractmethod | ||
def set(self, name: str, value, ex: Optional[int] = None): | ||
""" | ||
Set the value at key ``name`` to ``value`` | ||
``ex`` sets an expire flag on key ``name`` for ``ex`` seconds. | ||
""" | ||
pass | ||
|
||
@abstractmethod | ||
def expire(self, name: str, ex: int): | ||
""" | ||
Set an expire flag on key ``name`` for ``ex`` seconds | ||
""" | ||
pass | ||
|
||
@abstractmethod | ||
def incr(self, name: str) -> int: | ||
""" | ||
Increase the integer value of a key ``name`` by 1. | ||
If the key does not exist, it is set to 0 | ||
before performing the operation. | ||
Returns: | ||
The value of key ``name`` after the increment | ||
Raises: | ||
TypeError: if cache value is not an integer | ||
""" | ||
pass | ||
|
||
@abstractmethod | ||
def flushdb(self): | ||
""" | ||
Delete all keys in the current database | ||
""" | ||
pass | ||
|
||
@abstractmethod | ||
def delete(self, name: str): | ||
""" | ||
Delete the key specified by ``name`` | ||
""" | ||
pass | ||
|
||
|
||
class InMemoryCacheStore(CacheStoreInterface): | ||
class CacheValue(BaseModel): | ||
value: Any | ||
expired_at: Optional[datetime] | ||
|
||
def __init__(self): | ||
self._cache: dict[str, Optional[InMemoryCacheStore.CacheValue]] = {} | ||
|
||
def get(self, name: str) -> Any: | ||
current_time = datetime.now() | ||
data = self._cache.get(name) | ||
if data is None: | ||
return None | ||
if data.expired_at and current_time > data.expired_at: | ||
del self._cache[name] | ||
return None | ||
return data.value | ||
|
||
def set(self, name: str, value, ex: Optional[int] = None): | ||
self._cache[name] = InMemoryCacheStore.CacheValue( | ||
value=value, expired_at=None | ||
) | ||
if ex is not None: | ||
self.expire(name, ex) | ||
|
||
def expire(self, name: str, ex: int): | ||
current_time = datetime.now() | ||
expired_at = current_time + timedelta(seconds=ex) | ||
data = self._cache.get(name) | ||
if data is None: | ||
return | ||
data.expired_at = expired_at | ||
|
||
def incr(self, name: str) -> int: | ||
value = self.get(name) | ||
if value is None: | ||
self._cache[name] = InMemoryCacheStore.CacheValue( | ||
value=1, expired_at=None | ||
) | ||
return 1 | ||
if isinstance(value, int): | ||
value += 1 | ||
self.set(name, value) | ||
return value | ||
raise TypeError("value is not an integer") | ||
|
||
def flushdb(self): | ||
self._cache = {} | ||
|
||
def delete(self, name: str): | ||
if name in self._cache: | ||
del self._cache[name] | ||
|
||
|
||
class HazelcastCacheStore(CacheStoreInterface): | ||
def __init__(self): | ||
self._cache = hazelcast_client.get_map("cache_store").blocking() | ||
|
||
def get(self, name: str) -> Any: | ||
return self._cache.get(name) | ||
|
||
def set(self, name: str, value, ex: Optional[int] = None): | ||
self._cache.put(name, value, ex) | ||
|
||
def expire(self, name: str, ex: int): | ||
self._cache.set_ttl(name, ex) | ||
|
||
def incr(self, name: str) -> int: | ||
flag = False | ||
value = 0 | ||
while not flag: | ||
value = self._cache.get(name) | ||
if value is None: | ||
self._cache.set(name, 1) | ||
return 1 | ||
if not isinstance(value, int): | ||
raise TypeError("value is not an integer") | ||
|
||
flag = self._cache.replace_if_same(name, value, value + 1) | ||
|
||
return value + 1 | ||
|
||
def flushdb(self): | ||
self._cache.clear() | ||
|
||
def delete(self, name: str): | ||
self._cache.remove(name) | ||
|
||
|
||
cache_store = HazelcastCacheStore() |
Oops, something went wrong.