Spaces:
Running
Running
File size: 6,543 Bytes
2a065c3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | from django.shortcuts import render
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework import status
import sys
import os
import requests
# Add the typesense directory to Python path
typesense_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'extra', 'typesense')
sys.path.append(typesense_path)
from search_utility import SwaminiVatoSearch
# Initialize the search utility with embeddings enabled
book_searcher = SwaminiVatoSearch(use_embeddings=True)
@api_view(['POST'])
@permission_classes([AllowAny])
def search_books(request):
"""
API endpoint for semantic book search
POST /api/llm/search-books/
Body: {
"query": "What is the nature of God?",
"scripture": "swamini_vato" (optional),
"max_results": 5 (optional),
"max_tokens": 2000 (optional)
}
Returns: {
"query": "...",
"context": "...",
"sources": [...],
"num_sources": 3,
"total_chars": 1234
}
"""
try:
query = request.data.get('query')
if not query:
return Response(
{'error': 'Query parameter is required'},
status=status.HTTP_400_BAD_REQUEST
)
# Get optional parameters
scripture = request.data.get('scripture', 'swamini_vato')
max_results = request.data.get('max_results', 5)
max_tokens = request.data.get('max_tokens', 2000)
# Perform search and get context for RAG
context_data = book_searcher.get_context_for_rag(
query=query,
filters=None, # Can add chapter filters if needed
max_tokens=max_tokens,
num_results=max_results
)
# Add query to response
context_data['query'] = query
context_data['scripture'] = scripture
return Response(context_data, status=status.HTTP_200_OK)
except Exception as e:
return Response(
{'error': str(e)},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
@api_view(['GET'])
@permission_classes([AllowAny])
def get_random_verse(request):
"""
API endpoint to get a random verse
GET /api/llm/random-verse/
Returns: Random verse data
"""
try:
verse = book_searcher.get_random_vat()
if not verse:
return Response(
{'error': 'No verse found'},
status=status.HTTP_404_NOT_FOUND
)
return Response(verse, status=status.HTTP_200_OK)
except Exception as e:
return Response(
{'error': str(e)},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
@api_view(['POST'])
@permission_classes([AllowAny])
def serp_search(request):
"""
API endpoint for SERP (Search Engine Results Page) search
POST /api/llm/serp-search/
Body: {
"query": "search query",
"engine": "google" (optional, default: google),
"domain": "google.com" (optional, default: google.com),
"gl": "US" (optional, default: US),
"tbm": "" (optional, for image/news/video search),
"lang": "en" (optional, default: en)
}
Returns: SERP results from Bright Data API
"""
try:
query = request.data.get('query')
if not query:
return Response(
{'error': 'Query parameter is required'},
status=status.HTTP_400_BAD_REQUEST
)
# Get optional parameters with defaults
engine = request.data.get('engine', 'google')
domain = request.data.get('domain', 'google.com')
gl = request.data.get('gl', 'US')
tbm = request.data.get('tbm', '')
lang = request.data.get('lang', 'en')
# Set up headers
headers = {
'accept': '*/*',
'accept-language': 'en-US,en;q=0.9,gu;q=0.8,ru;q=0.7,hi;q=0.6',
'priority': 'u=1, i',
'referer': 'https://brightdata.com/products/serp-api',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36',
}
# Set up parameters
params = {
'engine': engine,
'q': query,
'domain': domain,
'gl': gl,
'tbm': tbm,
'lang': lang,
}
# Make request to Bright Data SERP API
response = requests.get(
'https://brightdata.com/web_api/serp_playground',
params=params,
headers=headers,
timeout=30 # 30 second timeout
)
# Check if request was successful
if response.status_code != 200:
return Response(
{
'error': 'SERP API request failed',
'status_code': response.status_code,
'details': response.text
},
status=status.HTTP_502_BAD_GATEWAY
)
# Return the JSON response
serp_data = response.json()
return Response({
'query': query,
'engine': engine,
'results': serp_data
}, status=status.HTTP_200_OK)
except requests.exceptions.Timeout:
return Response(
{'error': 'SERP API request timed out'},
status=status.HTTP_504_GATEWAY_TIMEOUT
)
except requests.exceptions.RequestException as e:
return Response(
{'error': f'SERP API request failed: {str(e)}'},
status=status.HTTP_502_BAD_GATEWAY
)
except Exception as e:
return Response(
{'error': str(e)},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
|