feat: add environment endpoint for weather, forecast, and sun data
Add GET /tools/environment endpoint that fetches weather, forecast, sun times, and air quality data from user's volatile Qdrant collection. - Add qdrant-client dependency - Create QdrantReadClient wrapper for read-only queries - Add environment schemas and service in tools domain - Parse weather, forecast, sun times, and air quality from Qdrant payloads - Support user-specific collections via preferred_username from OIDC - Add comprehensive service tests (13 tests) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
b8fca7060f
commit
6045c6ac6a
@@ -3,14 +3,20 @@ Tools Controller
|
||||
|
||||
Provides utility tool endpoints including:
|
||||
- DNS lookups
|
||||
- Environment data (weather, forecast, sun times, air quality)
|
||||
"""
|
||||
from fastapi import APIRouter, HTTPException, status
|
||||
from typing import Dict, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
|
||||
from src.controllers.base import BaseController
|
||||
from src.logging_config import get_logger
|
||||
from src.dns.schemas import DNSLookupRequest, DNSLookupResponse
|
||||
from src.dns.service import DNSService
|
||||
from src.dns.exceptions import DNSQueryError
|
||||
from src.domains.tools.environment.schemas import EnvironmentResponse
|
||||
from src.domains.tools.environment.service import get_environment_service
|
||||
from src.oidc.dependencies import get_optional_user
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
@@ -26,6 +32,7 @@ class ToolsController(BaseController):
|
||||
def __init__(self):
|
||||
super().__init__(prefix="/tools", tags=["Tools"])
|
||||
self.dns_service = DNSService()
|
||||
self.environment_service = get_environment_service()
|
||||
|
||||
def create_router(self) -> APIRouter:
|
||||
"""Create and configure the router"""
|
||||
@@ -95,6 +102,58 @@ class ToolsController(BaseController):
|
||||
detail="An unexpected error occurred during DNS lookup"
|
||||
)
|
||||
|
||||
@router.get(
|
||||
"/environment",
|
||||
response_model=EnvironmentResponse,
|
||||
status_code=status.HTTP_200_OK,
|
||||
summary="Get environment data",
|
||||
description="""
|
||||
Fetch current environment data including weather, forecast, sun times,
|
||||
and optionally air quality.
|
||||
|
||||
Data is retrieved from the user's volatile Qdrant collection which is
|
||||
populated by background data collectors.
|
||||
|
||||
**Data Sources:**
|
||||
- Weather: Current temperature, conditions, humidity, wind
|
||||
- Forecast: Multi-day weather outlook
|
||||
- Sun Times: Sunrise, sunset, daylight duration
|
||||
- Air Quality: AQI and pollutant levels (when available)
|
||||
|
||||
**Authentication:**
|
||||
- Uses authenticated user's `preferred_username` if available
|
||||
- Falls back to 'default' for unauthenticated requests
|
||||
"""
|
||||
)
|
||||
async def get_environment(
|
||||
user: Optional[Dict] = Depends(get_optional_user),
|
||||
) -> EnvironmentResponse:
|
||||
"""
|
||||
Get current environment data.
|
||||
|
||||
Args:
|
||||
user: Optional authenticated user info
|
||||
|
||||
Returns:
|
||||
Environment data with weather, forecast, sun times, and air quality
|
||||
"""
|
||||
try:
|
||||
# Determine user identifier
|
||||
user_id = "default"
|
||||
if user:
|
||||
user_id = user.get("preferred_username") or user.get("sub", "default")
|
||||
|
||||
logger.info(f"Fetching environment data for user: {user_id}")
|
||||
result = await self.environment_service.get_current(user_id)
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching environment data: {str(e)}", exc_info=True)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to fetch environment data"
|
||||
)
|
||||
|
||||
return router
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user