quivr/backend/modules/brain/service/call_brain_api.py

112 lines
3.5 KiB
Python
Raw Normal View History

from uuid import UUID
import requests
from logger import get_logger
logger = get_logger(__name__)
from fastapi import HTTPException
from modules.brain.entity.api_brain_definition_entity import ApiBrainDefinitionSchema
from modules.brain.service.api_brain_definition_service import ApiBrainDefinitionService
from modules.brain.service.brain_service import BrainService
brain_service = BrainService()
api_brain_definition_service = ApiBrainDefinitionService()
def get_api_call_response_as_text(
method, api_url, params, search_params, secrets
) -> str:
headers = {}
api_url_with_search_params = api_url
if search_params:
api_url_with_search_params += "?"
for search_param in search_params:
api_url_with_search_params += (
f"{search_param}={search_params[search_param]}&"
)
for secret in secrets:
headers[secret] = secrets[secret]
try:
if method in ["GET", "DELETE"]:
response = requests.request(
method,
url=api_url_with_search_params,
params=params or None,
headers=headers or None,
)
elif method in ["POST", "PUT", "PATCH"]:
response = requests.request(
method,
url=api_url_with_search_params,
json=params or None,
headers=headers or None,
)
else:
raise ValueError(f"Invalid method: {method}")
return response.text
except Exception as e:
logger.error(f"Error calling API: {e}")
return None
def extract_api_brain_definition_values_from_llm_output(
brain_schema: ApiBrainDefinitionSchema, arguments: dict
) -> dict:
params_values = {}
properties = brain_schema.properties
required_values = brain_schema.required
for property in properties:
if property.name in arguments:
if property.type == "number":
params_values[property.name] = float(arguments[property.name])
else:
params_values[property.name] = arguments[property.name]
continue
if property.name in required_values:
raise HTTPException(
status_code=400,
detail=f"Required parameter {property.name} not found in arguments",
)
return params_values
def call_brain_api(brain_id: UUID, user_id: UUID, arguments: dict) -> str:
brain_definition = api_brain_definition_service.get_api_brain_definition(brain_id)
if brain_definition is None:
raise HTTPException(
status_code=404, detail=f"Brain definition {brain_id} not found"
)
brain_params_values = extract_api_brain_definition_values_from_llm_output(
brain_definition.params, arguments
)
brain_search_params_values = extract_api_brain_definition_values_from_llm_output(
brain_definition.search_params, arguments
)
secrets = brain_definition.secrets
secrets_values = {}
for secret in secrets:
secret_value = brain_service.external_api_secrets_repository.read_secret(
user_id=user_id, brain_id=brain_id, secret_name=secret.name
)
secrets_values[secret.name] = secret_value
return get_api_call_response_as_text(
api_url=brain_definition.url,
params=brain_params_values,
search_params=brain_search_params_values,
secrets=secrets_values,
method=brain_definition.method,
)