Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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 .env.docker
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ REDIS_PORT="6379"
ELASTICSEARCH_URL=http://index:9200

# Chatbot
GOOGLE_APPLICATION_CREDENTIALS=
CHATBOT_CREDENTIALS=
BILLING_PROJECT_ID=
QUERY_PROJECT_ID=
MODEL_URI=
Expand Down
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ repos:
name: yamlfix
types: [yaml]
language: system
entry: yamlfix --exclude "charts/**/*" .
entry: yamlfix
exclude: ^charts/
18 changes: 3 additions & 15 deletions backend/apps/chatbot/agent/tools.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
import json
import os
from collections.abc import Callable
from functools import cache, wraps
from functools import wraps
from typing import Any, Literal, Self

import httpx
Expand All @@ -11,6 +10,8 @@
from langchain_core.tools import BaseTool, tool
from pydantic import BaseModel, model_validator

from backend.apps.chatbot.utils.gcloud import get_bigquery_client

# HTTPX Default Timeout
TIMEOUT = 5.0

Expand Down Expand Up @@ -234,19 +235,6 @@ def wrapper(*args, **kwargs) -> Any:
return decorator(_func)


@cache
def get_bigquery_client() -> bq.Client:
"""Return a cached BigQuery client.

The client is initialized once using the project ID from the
`QUERY_PROJECT_ID` environment variable and reused on subsequent calls.

Returns:
bigquery.Client: A cached, authenticated BigQuery client.
"""
return bq.Client(project=os.environ["QUERY_PROJECT_ID"])


@tool
@handle_tool_errors
def search_datasets(query: str) -> str:
Expand Down
3 changes: 2 additions & 1 deletion backend/apps/chatbot/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ class ChatbotConfig(AppConfig):
verbose_name = "Chatbot"

def ready(self):
# Enable logs from the chatbot package
import backend.apps.chatbot.checks # noqa: F401
import chatbot

# Enable logs from the chatbot package
logger.enable(chatbot.__name__)
66 changes: 66 additions & 0 deletions backend/apps/chatbot/checks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
import os

from django.core.checks import Warning, register


@register()
def check_gcloud_env_vars(app_configs, **kwargs):
"""Validate Google Cloud environment variables (warnings only)."""
warnings = []

sa_file = os.getenv("CHATBOT_CREDENTIALS")
if not sa_file:
warnings.append(
Warning(
"CHATBOT_CREDENTIALS not set - chatbot will be disabled",
hint="Set CHATBOT_CREDENTIALS=/path/to/service-account.json\n",
id="chatbot.W001",
)
)
elif not os.path.exists(sa_file):
warnings.append(
Warning(
f"Service account file {sa_file} not found - chatbot will be disabled",
hint="Ensure the file exists at the specified path\n",
id="chatbot.W002",
)
)

if not os.getenv("QUERY_PROJECT_ID"):
warnings.append(
Warning(
"QUERY_PROJECT_ID not set - chatbot will be disabled",
hint="Set QUERY_PROJECT_ID=your-gcp-project-id\n",
id="chatbot.W003",
)
)

if not os.getenv("MODEL_URI"):
warnings.append(
Warning(
"MODEL_URI not set - chatbot will be disabled",
hint="Set a valid model uri like 'google_vertexai:gemini-2.5-flash'\n",
id="chatbot.W004",
)
)

if not os.getenv("LANGCHAIN_TRACING_V2"):
warnings.append(
Warning(
"LANGCHAIN_TRACING_V2 not set - tracing will be disabled",
hint="Set LANGCHAIN_TRACING_V2=true\n",
id="chatbot.W005",
)
)

if not os.getenv("LANGCHAIN_API_KEY"):
warnings.append(
Warning(
"LANGCHAIN_API_KEY not set - tracing will be disabled",
hint="Set LANGCHAIN_API_KEY=your-langsmith-api-key\n",
id="chatbot.W006",
)
)

return warnings
47 changes: 47 additions & 0 deletions backend/apps/chatbot/utils/gcloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
import os
from functools import cache

from google.cloud import bigquery as bq
from google.oauth2.service_account import Credentials


@cache
def get_chatbot_credentials() -> Credentials:
"""Return cached Google Cloud service account credentials."""
sa_file = os.getenv("CHATBOT_CREDENTIALS")

if not sa_file:
raise ValueError(
"CHATBOT_CREDENTIALS environment variable must be set. "
"Please provide the path to your service account JSON file."
)

if not os.path.exists(sa_file):
raise FileNotFoundError(f"Service account file not found: {sa_file}")

return Credentials.from_service_account_file(sa_file)


@cache
def get_bigquery_client() -> bq.Client:
"""Return a cached BigQuery client.

The client is initialized once using the project ID from the
`QUERY_PROJECT_ID` environment variable and reused on subsequent calls.

Returns:
bigquery.Client: A cached, authenticated BigQuery client.
"""
project = os.getenv("QUERY_PROJECT_ID")

if not project:
raise ValueError(
"QUERY_PROJECT_ID environment variable must be set. "
"Please provide the ID of your BigQuery project."
)

return bq.Client(
project=project,
credentials=get_chatbot_credentials(),
)
5 changes: 4 additions & 1 deletion backend/apps/chatbot/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
ThreadSerializer,
UserMessageSerializer,
)
from backend.apps.chatbot.utils.gcloud import get_chatbot_credentials
from backend.apps.chatbot.utils.stream import EventData, StreamEvent, process_chunk

ModelSerializer = TypeVar("ModelSerializer", bound=Serializer)
Expand Down Expand Up @@ -336,7 +337,9 @@ def _get_sql_agent() -> Generator[ReActAgent]:

conn = f"postgresql://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}"

model = init_chat_model(MODEL_URI, temperature=0)
credentials = get_chatbot_credentials()

model = init_chat_model(MODEL_URI, temperature=0, credentials=credentials)

def start_hook(state: State):
messages = state["messages"]
Expand Down
2 changes: 2 additions & 0 deletions charts/basedosdados-api/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,5 @@ spec:
items:
- key: GCP_SA
path: gcp-sa.json
- key: CHATBOT_SA
path: chatbot-sa.json
2 changes: 1 addition & 1 deletion docker-compose.override.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ services:
database:
condition: service_healthy
healthcheck:
test: [CMD, curl, -f, http://localhost/healthcheck/]
test: [CMD, curl, -f, http://localhost:8000/healthcheck/]
interval: 1m
timeout: 30s
retries: 5
Expand Down
Loading