Spaces:
Paused
Paused
| from fastapi import FastAPI, HTTPException | |
| from fastapi.responses import StreamingResponse | |
| from fastapi.middleware.cors import CORSMiddleware | |
| import aiohttp | |
| import json | |
| import time | |
| import os | |
| from pydantic import BaseModel | |
| from apscheduler.schedulers.background import BackgroundScheduler | |
| app = FastAPI() | |
| # Enable CORS | |
| app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"]) | |
| # Time-Limited Infinite Cache | |
| cache = {} | |
| CACHE_DURATION = 120 | |
| # Function to clean up expired cache entries | |
| def cleanup_cache(): | |
| current_time = time.time() | |
| for key, (value, timestamp) in list(cache.items()): | |
| if current_time - timestamp > CACHE_DURATION: | |
| del cache[key] | |
| # Initialize and start the scheduler | |
| scheduler = BackgroundScheduler() | |
| scheduler.add_job(cleanup_cache, 'interval', seconds=60) # Run cleanup every 60 seconds | |
| scheduler.start() | |
| class StreamTextRequest(BaseModel): | |
| query: str | |
| history: str = "[]" | |
| model: str = "gpt-4" | |
| api_key: str = None | |
| async def stream_text(request: StreamTextRequest): | |
| current_time = time.time() | |
| cache_key = (request.query, request.history, request.model) | |
| # Check if the request is in the cache and not expired | |
| if cache_key in cache: | |
| cached_response, timestamp = cache[cache_key] | |
| return StreamingResponse(iter([f"{cached_response}"]), media_type='text/event-stream') | |
| # Use the API specified by the user | |
| api_url = "https://api.pawan.krd/unfiltered/v1" | |
| api_key = request.api_key if request.api_key != 'none' else os.environ.get("OPENAI_API_KEY") | |
| system_message = """You are an AI language assistant. Your sole task is to correct the grammar, spelling, and structure of the sentences provided to you. You must not change the meaning of the sentences, and you should focus only on making them grammatically correct, concise, and clear. Do not add any additional information or provide explanations unless specifically asked. Your responses should be limited to the corrected version of the sentence.""" | |
| messages = [{'role': 'system', 'content': system_message}] | |
| messages.extend(json.loads(request.history)) | |
| messages.append({'role': 'user', 'content': request.query}) | |
| data = { | |
| 'messages': messages, | |
| 'model': request.model, | |
| 'stream': True | |
| } | |
| async def stream_response(): | |
| async with aiohttp.ClientSession() as session: | |
| async with session.post( | |
| api_url, | |
| headers={'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json'}, | |
| json=data | |
| ) as response: | |
| if response.status != 200: | |
| raise HTTPException(status_code=response.status, detail="Error fetching AI response") | |
| async for line in response.content: | |
| line = line.decode('utf-8').strip() | |
| if line.startswith('data:'): | |
| json_data = line[6:] | |
| try: | |
| parsed_data = json.loads(json_data) | |
| content = parsed_data.get("choices", [{}])[0].get("delta", {}).get("content", '') | |
| if content: | |
| yield f"data: {content}\n\n" | |
| except json.JSONDecodeError as e: | |
| yield f"data: Error decoding JSON\n\n" | |
| # Cache the full response if available | |
| # response_content = "full response would be stored here if needed" | |
| # cache[cache_key] = (response_content, current_time) | |
| return StreamingResponse(stream_response(), media_type='text/event-stream') | |
| # Serve static files | |
| from starlette.responses import FileResponse | |
| async def script1_js(): | |
| return FileResponse("script1.js") | |
| async def script2_js(): | |
| return FileResponse("script2.js") | |
| async def styles_css(): | |
| return FileResponse("styles.css") | |
| async def read_index(): | |
| return FileResponse('index.html') | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=7068, reload=True) | |