Spaces:
Sleeping
Sleeping
| 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) | |
| 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 | |
| ) | |
| 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 | |
| ) | |
| 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 | |
| ) | |