FIXED: timeoutError with gif seach and sending
This commit is contained in:
parent
1b71c63919
commit
d811fc1b4e
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,22 +1,20 @@
|
||||||
"""
|
|
||||||
controllers/tenor.py — GIPHY API proxy (requests-based).
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
from bottle import route, request, response
|
from bottle import route, request, response
|
||||||
|
import redis
|
||||||
|
|
||||||
|
redis_server = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True)
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
_giphy_key: str = "GIPHY_API_KEY"
|
_giphy_key: str = "NR2vkCSTVKnwBx9IavODcsqeSt9Sreze"
|
||||||
_session = requests.Session()
|
_session = requests.Session()
|
||||||
_session.headers.update({'User-Agent': 'GIPHY-Proxy/1.0'})
|
_session.headers.update({'User-Agent': 'GIPHY-Proxy/1.0'})
|
||||||
|
|
||||||
GIPHY_BASE = "https://api.giphy.com/v1/gifs"
|
GIPHY_BASE = "https://api.giphy.com/v1/gifs"
|
||||||
|
|
||||||
|
|
||||||
def init(tenor_cfg):
|
def init(tenor_cfg):
|
||||||
global _giphy_key
|
global _giphy_key
|
||||||
if hasattr(tenor_cfg, 'api_key') and tenor_cfg.api_key:
|
if hasattr(tenor_cfg, 'api_key') and tenor_cfg.api_key:
|
||||||
|
|
@ -25,23 +23,26 @@ def init(tenor_cfg):
|
||||||
else:
|
else:
|
||||||
logger.warning("No GIPHY API key configured, using default placeholder")
|
logger.warning("No GIPHY API key configured, using default placeholder")
|
||||||
|
|
||||||
|
|
||||||
def _build_params(query_params, extra=None):
|
def _build_params(query_params, extra=None):
|
||||||
params = {
|
params = {
|
||||||
"api_key": _giphy_key,
|
"api_key": _giphy_key,
|
||||||
"limit": query_params.get("limit", "20"),
|
"limit": int(query_params.get("limit", "20")),
|
||||||
"rating": query_params.get("rating", "g"),
|
"rating": query_params.get("rating", "g"),
|
||||||
"lang": query_params.get("lang", "en"),
|
"lang": query_params.get("lang", "en"),
|
||||||
}
|
}
|
||||||
if query_params.get("offset"):
|
# Обработка offset
|
||||||
params["offset"] = query_params["offset"]
|
try:
|
||||||
|
if query_params.get("offset"):
|
||||||
|
params["offset"] = int(query_params["offset"])
|
||||||
|
else:
|
||||||
|
params["offset"] = 0
|
||||||
|
except ValueError:
|
||||||
|
params["offset"] = 0
|
||||||
if extra:
|
if extra:
|
||||||
params.update(extra)
|
params.update(extra)
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
|
||||||
def _transform_giphy_result(gif):
|
def _transform_giphy_result(gif):
|
||||||
"""Convert GIPHY format -> unified {id, title, file: {hd, md, sm, xs}}."""
|
|
||||||
images = gif.get("images", {})
|
images = gif.get("images", {})
|
||||||
return {
|
return {
|
||||||
"id": gif.get("id"),
|
"id": gif.get("id"),
|
||||||
|
|
@ -56,10 +57,9 @@ def _transform_giphy_result(gif):
|
||||||
"blur_preview": images.get("preview_gif", {}).get("url", ""),
|
"blur_preview": images.get("preview_gif", {}).get("url", ""),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _fetch_giphy(endpoint, params):
|
def _fetch_giphy(endpoint, params):
|
||||||
url = f"{GIPHY_BASE}/{endpoint}"
|
url = f"{GIPHY_BASE}/{endpoint}"
|
||||||
logger.debug(f"GET {url}")
|
logger.debug(f"GET {url} with params {params}")
|
||||||
try:
|
try:
|
||||||
resp = _session.get(url, params=params, timeout=15)
|
resp = _session.get(url, params=params, timeout=15)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
|
|
@ -68,13 +68,16 @@ def _fetch_giphy(endpoint, params):
|
||||||
if isinstance(results, dict):
|
if isinstance(results, dict):
|
||||||
results = [results]
|
results = [results]
|
||||||
transformed = [_transform_giphy_result(g) for g in results]
|
transformed = [_transform_giphy_result(g) for g in results]
|
||||||
|
per_page = int(params.get("limit", 20))
|
||||||
|
current_offset = int(params.get("offset", 0))
|
||||||
|
total_results = len(transformed)
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"results": transformed,
|
"results": transformed,
|
||||||
"pagination": {
|
"pagination": {
|
||||||
"current_page": (int(params.get("offset", 0)) // max(int(params.get("limit", 20)), 1)) + 1,
|
"current_page": (current_offset // per_page) + 1,
|
||||||
"per_page": params.get("limit", 20),
|
"per_page": per_page,
|
||||||
"has_next": len(transformed) >= int(params.get("limit", 20)),
|
"has_next": total_results >= per_page,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
|
|
@ -88,20 +91,41 @@ def _fetch_giphy(endpoint, params):
|
||||||
response.status = 502
|
response.status = 502
|
||||||
return {"success": False, "error": error_msg}
|
return {"success": False, "error": error_msg}
|
||||||
|
|
||||||
|
|
||||||
def register_routes(app):
|
def register_routes(app):
|
||||||
@app.route("/api/gifs/trending", method="GET")
|
@app.route("/api/gifs/trending", method="GET")
|
||||||
def gifs_trending():
|
def gifs_trending():
|
||||||
logger.debug(f"Trending request: {dict(request.query)}")
|
try:
|
||||||
params = _build_params(request.query)
|
logger.debug(f"Trending request: {dict(request.query)}")
|
||||||
return _fetch_giphy("trending", params)
|
params = _build_params(request.query)
|
||||||
|
answ = _fetch_giphy("trending", params)
|
||||||
|
serialized_answ = json.dumps(answ)
|
||||||
|
redis_server.set('trending', serialized_answ, ex=360)
|
||||||
|
return json.loads(serialized_answ)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in trending route")
|
||||||
|
response.status = 500
|
||||||
|
return {"success": False, "error": str(e)}
|
||||||
|
|
||||||
@app.route("/api/gifs/search", method="GET")
|
@app.route("/api/gifs/search", method="GET")
|
||||||
def gifs_search():
|
def gifs_search():
|
||||||
logger.debug(f"Search request: {dict(request.query)}")
|
try:
|
||||||
q = request.query.get("q", "")
|
logger.debug(f"Search request: {dict(request.query)}")
|
||||||
if not q:
|
q = request.query.get("q", "")
|
||||||
response.status = 400
|
if not q:
|
||||||
return {"success": False, "error": "Missing query"}
|
response.status = 400
|
||||||
params = _build_params(request.query, extra={"q": q})
|
return {"success": False, "error": "Missing query parameter 'q'"}
|
||||||
return _fetch_giphy("search", params)
|
params = _build_params(request.query, extra={"q": q})
|
||||||
|
cache_key = f"search:{q.lower().strip()}"
|
||||||
|
# Проверка кеша
|
||||||
|
cached = redis_server.get(cache_key)
|
||||||
|
if cached:
|
||||||
|
return json.loads(cached)
|
||||||
|
# Если нет кеша, делаем запрос
|
||||||
|
answ = _fetch_giphy("search", params)
|
||||||
|
serialized_answ = json.dumps(answ)
|
||||||
|
redis_server.set(cache_key, serialized_answ, ex=360)
|
||||||
|
return answ
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error in search route")
|
||||||
|
response.status = 500
|
||||||
|
return {"success": False, "error": str(e)}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue