remove valkey caching functionality from metadata relay in favour of caching by a cdn like cloudflare

This commit is contained in:
maxDorninger
2025-11-02 21:22:58 +01:00
parent c38995579c
commit 252f8c2f65
4 changed files with 2 additions and 90 deletions

View File

@@ -1,7 +1,7 @@
# MetadataRelay
This is a service that provides metadata for movies and TV shows. It caches the metadata to not overload the TMDB and
TVDB APIs. This service is used by MediaManager to fetch metadata for movies and TV shows. I (the developer) run a
This is a service that provides metadata for movies and TV shows. It is advisable to use a load balancer/CDN like
Cloudflare to cache requests as to not overload the TMDB/TVDB api. I (the developer) run a
public instance of this service at https://metadata-relay.dorninger.co, but you can also run your
own instance.
@@ -9,19 +9,12 @@ own instance.
````yaml
services:
valkey:
image: valkey/valkey:latest
restart: always
container_name: valkey
expose:
- 6379
metadata_relay:
image: ghcr.io/maxdorninger/mediamanager/metadata_relay:latest
restart: always
environment:
- TMDB_API_KEY= # you need not provide a TMDB API key, if you only want to use TVDB metadata, or the other way around
- TVDB_API_KEY=
- VALKEY_HOST=valkey
container_name: metadata_relay
ports:
- 8000:8000

View File

@@ -1,65 +0,0 @@
import json
import hashlib
import logging
from typing import Any, Optional
import valkey.asyncio as valkey
import os
from functools import wraps
log = logging.getLogger(__name__)
redis_client = valkey.Redis(
host=os.getenv("VALKEY_HOST", "localhost"),
port=int(os.getenv("VALKEY_PORT", 6379)),
db=int(os.getenv("VALKEY_DB", 0)),
decode_responses=True,
)
def generate_cache_key(prefix: str, *args, **kwargs) -> str:
key_data = f"{prefix}:{args}:{sorted(kwargs.items())}"
return hashlib.md5(key_data.encode()).hexdigest()
async def get_cached_response(cache_key: str) -> Optional[Any]:
try:
cached_data = await redis_client.get(cache_key)
if cached_data:
return json.loads(cached_data)
return None
except Exception as e:
log.error(f"Error getting cached response: {e}")
return None
async def set_cached_response(cache_key: str, data: Any, ttl: int = 3600) -> bool:
try:
await redis_client.setex(cache_key, ttl, json.dumps(data, default=str))
return True
except Exception as e:
log.error(f"Error setting cached response: {e}")
return False
def cache_response(prefix: str, ttl: int = 3600):
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
cache_key = generate_cache_key(prefix, *args, **kwargs)
cached_response = await get_cached_response(cache_key)
if cached_response is not None:
log.info(f"Cache hit for key: {cache_key}")
return cached_response
log.info(f"Cache miss for key: {cache_key}")
response = await func(*args, **kwargs)
await set_cached_response(cache_key, response, ttl)
return response
return wrapper
return decorator

View File

@@ -4,7 +4,6 @@ import os
import tmdbsimple
from tmdbsimple import TV, TV_Seasons, Movies, Trending, Search
from fastapi import APIRouter
from .cache import cache_response
log = logging.getLogger(__name__)
@@ -17,36 +16,29 @@ else:
tmdbsimple.API_KEY = tmdb_api_key
@router.get("/tv/trending")
@cache_response("tmdb_tv_trending", ttl=7200)
async def get_tmdb_trending_tv():
return Trending(media_type="tv").info()
@router.get("/tv/search")
@cache_response("tmdb_tv_search", ttl=14400)
async def search_tmdb_tv(query: str, page: int = 1):
return Search().tv(page=page, query=query, include_adult=True)
@router.get("/tv/shows/{show_id}")
@cache_response("tmdb_tv_show", ttl=28800)
async def get_tmdb_show(show_id: int):
return TV(show_id).info()
@router.get("/tv/shows/{show_id}/{season_number}")
@cache_response("tmdb_tv_season", ttl=28800)
async def get_tmdb_season(season_number: int, show_id: int):
return TV_Seasons(season_number=season_number, tv_id=show_id).info()
@router.get("/movies/trending")
@cache_response("tmdb_movies_trending", ttl=7200)
async def get_tmdb_trending_movies():
return Trending(media_type="movie").info()
@router.get("/movies/search")
@cache_response("tmdb_movies_search", ttl=14400)
async def search_tmdb_movies(query: str, page: int = 1):
return Search().movie(page=page, query=query, include_adult=True)
@router.get("/movies/{movie_id}")
@cache_response("tmdb_movie", ttl=28800)
async def get_tmdb_movie(movie_id: int):
return Movies(movie_id).info()

View File

@@ -3,7 +3,6 @@ import os
import tvdb_v4_official
import logging
from fastapi import APIRouter
from .cache import cache_response
log = logging.getLogger(__name__)
@@ -17,36 +16,29 @@ else:
tvdb_client = tvdb_v4_official.TVDB(tvdb_api_key)
@router.get("/tv/trending")
@cache_response("tvdb_tv_trending", ttl=7200)
async def get_tvdb_trending_tv():
return tvdb_client.get_all_series()
@router.get("/tv/search")
@cache_response("tvdb_tv_search", ttl=14400)
async def search_tvdb_tv(query: str):
return tvdb_client.search(query)
@router.get("/tv/shows/{show_id}")
@cache_response("tvdb_tv_show", ttl=28800)
async def get_tvdb_show(show_id: int):
return tvdb_client.get_series_extended(show_id)
@router.get("/tv/seasons/{season_id}")
@cache_response("tvdb_tv_season", ttl=28800)
async def get_tvdb_season(season_id: int):
return tvdb_client.get_season_extended(season_id)
@router.get("/movies/trending")
@cache_response("tvdb_movies_trending", ttl=7200)
async def get_tvdb_trending_movies():
return tvdb_client.get_all_movies()
@router.get("/movies/search")
@cache_response("tvdb_movies_search", ttl=14400)
async def search_tvdb_movies(query: str):
return tvdb_client.search(query)
@router.get("/movies/{movie_id}")
@cache_response("tvdb_movie", ttl=28800)
async def get_tvdb_movie(movie_id: int):
return tvdb_client.get_movie_extended(movie_id)