Skip to content

Commit fa97f5a

Browse files
Sai Rishi SSai Rishi S
authored andcommitted
feat: leveraged Redis to store sontext in cache
1 parent 43b7707 commit fa97f5a

5 files changed

Lines changed: 83 additions & 16 deletions

File tree

app/api/router.py

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
from app.tools.presentation_generator.tools.slides_generator import SlidesGenerator
1313
import uuid
1414
from fastapi import FastAPI
15+
from fastapi import Request
16+
import json
17+
from app.services.cache_service import CacheInterface
1518

1619
logger = setup_logger(__name__)
1720
router = APIRouter()
@@ -21,6 +24,11 @@
2124
if not hasattr(app.state, "presentation_contexts"):
2225
app.state.presentation_contexts = {}
2326

27+
28+
# Dependency injection
29+
async def get_cache_service(request: Request) -> CacheInterface:
30+
return request.app.state.cache_service
31+
2432
@router.get("/")
2533
def read_root():
2634
return {"Hello": "World"}
@@ -29,20 +37,27 @@ def read_root():
2937
# 1. Generate outline with initial inputs
3038
# 2. Generate slides using stored outline and inputs
3139
@router.post("/generate-outline", response_model=Union[ToolResponse, ErrorResponse])
32-
async def generate_outline(data: ToolRequest, _ = Depends(key_check)):
40+
async def generate_outline(
41+
data: ToolRequest,
42+
cache: CacheInterface = Depends(get_cache_service),
43+
_ = Depends(key_check)
44+
):
3345
try:
34-
# Execute outline generation and store context for slides
46+
# Potential Bottleneck: execute tool can be a blocking operation
47+
# Solution: Use Redis Queue or Celery for background tasks
48+
# Execute outline generation and store context for slides generation
3549
request_data = data.tool_data
3650
requested_tool = load_tool_metadata(request_data.tool_id)
3751
request_inputs_dict = finalize_inputs(request_data.inputs, requested_tool['inputs'])
3852
result = execute_tool(request_data.tool_id, request_inputs_dict)
3953

40-
# Store in app state, to use as context for slides generation
54+
# Store in app cache, to use as context for slides generation
4155
presentation_id = str(uuid.uuid4())
42-
app.state.presentation_contexts[presentation_id] = {
43-
"outline": result,
44-
"inputs": request_inputs_dict
45-
}
56+
57+
await cache.set(
58+
f"presentation:{presentation_id}",
59+
json.dumps({"outline": result, "inputs": request_inputs_dict})
60+
)
4661

4762
return ToolResponse(data={
4863
"outline": result,
@@ -64,16 +79,17 @@ async def generate_outline(data: ToolRequest, _ = Depends(key_check)):
6479
)
6580

6681
@router.post("/generate-slides/{presentation_id}", response_model=Union[ToolResponse, ErrorResponse])
67-
async def generate_slides(presentation_id: str, _ = Depends(key_check)):
82+
async def generate_slides(
83+
presentation_id: str,
84+
cache: CacheInterface = Depends(get_cache_service),
85+
_ = Depends(key_check)
86+
):
6887
try:
69-
# Retrieve stored context and generate slides
70-
context = app.state.presentation_contexts.get(presentation_id)
71-
if not context:
72-
raise HTTPException(
73-
status_code=404,
74-
detail="Presentation context not found"
75-
)
88+
context_str = await cache.get(f"presentation:{presentation_id}")
89+
if not context_str:
90+
raise HTTPException(status_code=404)
7691

92+
context = json.loads(context_str)
7793
slides = SlidesGenerator(
7894
outline=context["outline"],
7995
inputs=context["inputs"]

app/main.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from contextlib import asynccontextmanager
66
from app.api.router import router
77
from app.services.logger import setup_logger
8+
from app.services.cache_service import RedisService
89
from app.api.error_utilities import ErrorResponse
910

1011
import os
@@ -18,6 +19,10 @@
1819
async def lifespan(app: FastAPI):
1920
logger.info(f"Initializing Application Startup")
2021
logger.info(f"Successfully Completed Application Startup")
22+
23+
app.state.cache_service = RedisService()
24+
25+
logger.info(f"Cache Service Initialized")
2126

2227
yield
2328
logger.info("Application shutdown")

app/services/cache_service.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from redis.asyncio import Redis
2+
from abc import ABC, abstractmethod
3+
import os
4+
5+
# Abstract interface (SOLID - Interface Segregation)
6+
class CacheInterface(ABC):
7+
@abstractmethod
8+
async def get(self, key: str): pass
9+
10+
@abstractmethod
11+
async def set(self, key: str, value: str, ttl: int = None): pass
12+
13+
# Concrete implementation
14+
class RedisService(CacheInterface):
15+
def __init__(self, redis_client: Redis = None):
16+
self.client = redis_client or Redis(
17+
host=os.getenv('REDIS_HOST', 'redis'),
18+
port=int(os.getenv('REDIS_PORT', 6379)),
19+
db=int(os.getenv('REDIS_DB', 0)),
20+
decode_responses=True
21+
)
22+
23+
async def get(self, key: str):
24+
return await self.client.get(key)
25+
26+
async def set(self, key: str, value: str, ttl: int = None):
27+
return await self.client.set(key, value, ex=ttl)

docker-compose.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
services:
2+
app:
3+
build: .
4+
ports:
5+
- "8000:8000"
6+
volumes:
7+
- .:/app # Enables live code changes
8+
env_file:
9+
- app/.env # Path to your .env file
10+
depends_on:
11+
- redis
12+
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload # --reload for live changes
13+
14+
redis:
15+
image: redis
16+
ports:
17+
- "6379:6379"

requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@ psutil
3737
pydub
3838
ffmpeg-python
3939
speechrecognition
40-
google-cloud-speech
40+
google-cloud-speech
41+
redis[hiredis]>=5.0.0
42+
aioredis>=2.0.0

0 commit comments

Comments
 (0)