perf(zopk): Cache dla grafu relacji (TTL 5 min)

- Dodano in-memory cache dla API /api/zopk/knowledge/graph/data
- Cache key oparty o parametry: entity_type, min_cooccurrence, limit
- TTL = 300 sekund (5 minut)
- Flaga 'cached' w odpowiedzi informuje czy dane z cache

Korzyść: Drugie i kolejne ładowania grafu są natychmiastowe.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-17 09:34:52 +01:00
parent 36d24d1735
commit b69882bbb2

45
app.py
View File

@ -11921,23 +11921,43 @@ def admin_zopk_knowledge_graph():
return render_template('admin/zopk_knowledge_graph.html')
# Cache for graph data (in-memory with TTL)
_graph_cache = {}
_GRAPH_CACHE_TTL = 300 # 5 minutes
@app.route('/api/zopk/knowledge/graph/data')
@login_required
def api_zopk_knowledge_graph_data():
"""Get graph data for entity co-occurrence visualization."""
"""Get graph data for entity co-occurrence visualization.
Uses in-memory cache with 5 minute TTL to avoid recalculating
co-occurrences on every request.
"""
import time
if not current_user.is_admin:
return jsonify({'success': False, 'error': 'Brak uprawnień'}), 403
from sqlalchemy import text, func
from database import ZOPKKnowledgeEntity, ZOPKKnowledgeEntityMention
# Build cache key from parameters
entity_type = request.args.get('entity_type', '')
min_cooccurrence = int(request.args.get('min_cooccurrence', 3))
limit = min(int(request.args.get('limit', 100)), 500)
cache_key = f"graph:{entity_type}:{min_cooccurrence}:{limit}"
# Check cache
if cache_key in _graph_cache:
cached_data, cached_time = _graph_cache[cache_key]
if time.time() - cached_time < _GRAPH_CACHE_TTL:
# Return cached data with cache indicator
cached_data['cached'] = True
return jsonify(cached_data)
db = SessionLocal()
try:
# Filter parameters
entity_type = request.args.get('entity_type', '')
min_cooccurrence = int(request.args.get('min_cooccurrence', 3))
limit = min(int(request.args.get('limit', 100)), 500)
# Get top entities by mentions
entities_query = db.query(ZOPKKnowledgeEntity).filter(
ZOPKKnowledgeEntity.mentions_count >= 5
@ -12008,15 +12028,22 @@ def api_zopk_knowledge_graph_data():
'verified': e.is_verified
})
return jsonify({
# Build response
response_data = {
'success': True,
'nodes': nodes,
'links': links,
'stats': {
'total_nodes': len(nodes),
'total_links': len(links)
}
})
},
'cached': False
}
# Save to cache
_graph_cache[cache_key] = (response_data.copy(), time.time())
return jsonify(response_data)
except Exception as e:
logger.error(f"Error getting graph data: {e}")