Final project commit: MTGJSON data integration and backend API
This commit is contained in:
@@ -0,0 +1,674 @@
|
||||
"""
|
||||
Card interaction router for MTG card interaction database.
|
||||
|
||||
Provides endpoints for searching card synergies, counters, evolutions,
|
||||
and getting recommendations based on card interactions.
|
||||
"""
|
||||
from typing import Optional, List, Dict, Any
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import text
|
||||
|
||||
from app.core.database import mtg_get_db
|
||||
from app.core.redis_client import cache_get, cache_set
|
||||
|
||||
router = APIRouter(prefix="/interactions", tags=["Card Interactions"])
|
||||
|
||||
|
||||
@router.get("/synergies/{card_id}")
|
||||
async def get_card_synergies(
|
||||
card_id: int,
|
||||
synergy_type: Optional[str] = Query(None, description="Filter by synergy type (archetype, mechanic, mana, combo)"),
|
||||
min_strength: int = Query(1, ge=1, le=5, description="Minimum synergy strength"),
|
||||
limit: int = Query(100, ge=1, le=500, description="Maximum results"),
|
||||
offset: int = Query(0, ge=0, description="Number of results to skip"),
|
||||
db: AsyncSession = Depends(mtg_get_db),
|
||||
):
|
||||
"""
|
||||
Get synergies for a specific card.
|
||||
|
||||
Synergies are positive interactions where cards work well together.
|
||||
"""
|
||||
cache_key = f"synergies:{card_id}:{synergy_type}:{min_strength}:{limit}:{offset}"
|
||||
|
||||
try:
|
||||
cached = await cache_get(cache_key)
|
||||
if cached:
|
||||
return {"cached": True, "results": cached}
|
||||
|
||||
# Build query
|
||||
conditions = ["card_a_id = :card_id OR card_b_id = :card_id"]
|
||||
params = {"card_id": card_id}
|
||||
|
||||
if synergy_type:
|
||||
conditions.append("synergy_type = :synergy_type")
|
||||
params["synergy_type"] = synergy_type
|
||||
|
||||
if min_strength:
|
||||
conditions.append("strength >= :min_strength")
|
||||
params["min_strength"] = min_strength
|
||||
|
||||
where_clause = " AND ".join(conditions)
|
||||
|
||||
query = f"""
|
||||
SELECT id, card_a_id, card_b_id, synergy_type, strength, notes, confidence
|
||||
FROM mtg_card_synergies
|
||||
WHERE {where_clause}
|
||||
ORDER BY strength DESC, confidence DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
"""
|
||||
params["limit"] = limit
|
||||
params["offset"] = offset
|
||||
|
||||
# Execute query
|
||||
result = await db.execute(text(query), params)
|
||||
rows = result.fetchall()
|
||||
|
||||
synergies = []
|
||||
for row in rows:
|
||||
synergies.append({
|
||||
"id": row[0],
|
||||
"card_a_id": row[1],
|
||||
"card_b_id": row[2],
|
||||
"synergy_type": row[3],
|
||||
"strength": row[4],
|
||||
"notes": row[5],
|
||||
"confidence": row[6],
|
||||
})
|
||||
|
||||
# Get count for pagination
|
||||
count_query = f"""
|
||||
SELECT COUNT(*)
|
||||
FROM mtg_card_synergies
|
||||
WHERE {where_clause}
|
||||
"""
|
||||
count_result = await db.execute(text(count_query), params)
|
||||
total = count_result.scalar()
|
||||
|
||||
# Cache for 10 minutes
|
||||
await cache_set(cache_key, {"synergies": synergies, "total": total}, ttl=600)
|
||||
|
||||
return {
|
||||
"cached": False,
|
||||
"results": synergies,
|
||||
"pagination": {
|
||||
"total": total,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
}
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Error fetching synergies: {str(e)}")
|
||||
|
||||
|
||||
@router.get("/counters/{card_id}")
|
||||
async def get_card_counters(
|
||||
card_id: int,
|
||||
counter_type: Optional[str] = Query(None, description="Filter by counter type (color, stats, spell, keyword)"),
|
||||
min_strength: int = Query(1, ge=1, le=5, description="Minimum counter strength"),
|
||||
limit: int = Query(100, ge=1, le=500, description="Maximum results"),
|
||||
offset: int = Query(0, ge=0, description="Number of results to skip"),
|
||||
db: AsyncSession = Depends(mtg_get_db),
|
||||
):
|
||||
"""
|
||||
Get counters for a specific card.
|
||||
|
||||
Counters are negative interactions where one card is disadvantaged by another.
|
||||
"""
|
||||
cache_key = f"counters:{card_id}:{counter_type}:{min_strength}:{limit}:{offset}"
|
||||
|
||||
cached = await cache_get(cache_key)
|
||||
if cached:
|
||||
return {"cached": True, "results": cached}
|
||||
|
||||
conditions = ["card_a_id = :card_id OR card_b_id = :card_id"]
|
||||
params = {"card_id": card_id}
|
||||
|
||||
if counter_type:
|
||||
conditions.append("counter_type = :counter_type")
|
||||
params["counter_type"] = counter_type
|
||||
|
||||
if min_strength:
|
||||
conditions.append("strength >= :min_strength")
|
||||
params["min_strength"] = min_strength
|
||||
|
||||
where_clause = " AND ".join(conditions)
|
||||
|
||||
query = f"""
|
||||
SELECT id, card_a_id, card_b_id, counter_type, strength, notes, confidence
|
||||
FROM mtg_card_counters
|
||||
WHERE {where_clause}
|
||||
ORDER BY strength DESC, confidence DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
"""
|
||||
params["limit"] = limit
|
||||
params["offset"] = offset
|
||||
|
||||
result = await db.execute(text(query), params)
|
||||
rows = result.fetchall()
|
||||
|
||||
counters = []
|
||||
for row in rows:
|
||||
counters.append({
|
||||
"id": row[0],
|
||||
"card_a_id": row[1],
|
||||
"card_b_id": row[2],
|
||||
"counter_type": row[3],
|
||||
"strength": row[4],
|
||||
"notes": row[5],
|
||||
"confidence": row[6],
|
||||
})
|
||||
|
||||
count_query = f"""
|
||||
SELECT COUNT(*)
|
||||
FROM mtg_card_counters
|
||||
WHERE {where_clause}
|
||||
"""
|
||||
count_result = await db.execute(text(count_query), params)
|
||||
total = count_result.scalar()
|
||||
|
||||
await cache_set(cache_key, {"counters": counters, "total": total}, ttl=600)
|
||||
|
||||
return {
|
||||
"cached": False,
|
||||
"results": counters,
|
||||
"pagination": {
|
||||
"total": total,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@router.get("/evolutions/{card_id}")
|
||||
async def get_card_evolutions(
|
||||
card_id: int,
|
||||
evolution_type: Optional[str] = Query(None, description="Filter by evolution type (reprint, transform, double_sided)"),
|
||||
min_strength: int = Query(1, ge=1, le=5, description="Minimum strength"),
|
||||
limit: int = Query(100, ge=1, le=500, description="Maximum results"),
|
||||
offset: int = Query(0, ge=0, description="Number of results to skip"),
|
||||
db: AsyncSession = Depends(mtg_get_db),
|
||||
):
|
||||
"""
|
||||
Get evolutions for a specific card.
|
||||
|
||||
Evolutions track when a card has been reprinted, transformed, or evolved.
|
||||
"""
|
||||
cache_key = f"evolutions:{card_id}:{evolution_type}:{min_strength}:{limit}:{offset}"
|
||||
|
||||
cached = await cache_get(cache_key)
|
||||
if cached:
|
||||
return {"cached": True, "results": cached}
|
||||
|
||||
conditions = ["card_id = :card_id"]
|
||||
params = {"card_id": card_id}
|
||||
|
||||
if evolution_type:
|
||||
conditions.append("evolution_type = :evolution_type")
|
||||
params["evolution_type"] = evolution_type
|
||||
|
||||
if min_strength:
|
||||
conditions.append("strength >= :min_strength")
|
||||
params["min_strength"] = min_strength
|
||||
|
||||
where_clause = " AND ".join(conditions)
|
||||
|
||||
query = f"""
|
||||
SELECT id, card_id, evolved_card_id, evolution_type, strength, notes, confidence
|
||||
FROM mtg_card_evolution
|
||||
WHERE {where_clause}
|
||||
ORDER BY strength DESC, confidence DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
"""
|
||||
params["limit"] = limit
|
||||
params["offset"] = offset
|
||||
|
||||
result = await db.execute(text(query), params)
|
||||
rows = result.fetchall()
|
||||
|
||||
evolutions = []
|
||||
for row in rows:
|
||||
evolutions.append({
|
||||
"id": row[0],
|
||||
"card_id": row[1],
|
||||
"evolved_card_id": row[2],
|
||||
"evolution_type": row[3],
|
||||
"strength": row[4],
|
||||
"notes": row[5],
|
||||
"confidence": row[6],
|
||||
})
|
||||
|
||||
count_query = f"""
|
||||
SELECT COUNT(*)
|
||||
FROM mtg_card_evolution
|
||||
WHERE {where_clause}
|
||||
"""
|
||||
count_result = await db.execute(text(count_query), params)
|
||||
total = count_result.scalar()
|
||||
|
||||
await cache_set(cache_key, {"evolutions": evolutions, "total": total}, ttl=600)
|
||||
|
||||
return {
|
||||
"cached": False,
|
||||
"results": evolutions,
|
||||
"pagination": {
|
||||
"total": total,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@router.get("/recommend/{card_id}")
|
||||
async def get_card_recommendations(
|
||||
card_id: int,
|
||||
recommendation_type: str = Query("synergy", description="Type of recommendation (synergy, counter, evolution)"),
|
||||
limit: int = Query(10, ge=1, le=100, description="Maximum results"),
|
||||
db: AsyncSession = Depends(mtg_get_db),
|
||||
):
|
||||
"""
|
||||
Get interaction recommendations for a card.
|
||||
|
||||
Provides cards that work well together or counter a specific card.
|
||||
"""
|
||||
cache_key = f"recommend:{card_id}:{recommendation_type}:{limit}"
|
||||
|
||||
cached = await cache_get(cache_key)
|
||||
if cached:
|
||||
return {"cached": True, "results": cached}
|
||||
|
||||
if recommendation_type == "synergy":
|
||||
# Get cards that synergize with this card
|
||||
query = """
|
||||
SELECT
|
||||
CASE WHEN card_a_id = :card_id THEN card_b_id ELSE card_a_id END as recommended_card_id,
|
||||
strength,
|
||||
synergy_type,
|
||||
confidence
|
||||
FROM mtg_card_synergies
|
||||
WHERE card_a_id = :card_id OR card_b_id = :card_id
|
||||
ORDER BY strength DESC, confidence DESC
|
||||
LIMIT :limit
|
||||
"""
|
||||
elif recommendation_type == "counter":
|
||||
# Get cards that counter this card
|
||||
query = """
|
||||
SELECT
|
||||
CASE WHEN card_a_id = :card_id THEN card_b_id ELSE card_a_id END as recommended_card_id,
|
||||
strength,
|
||||
counter_type,
|
||||
confidence
|
||||
FROM mtg_card_counters
|
||||
WHERE card_a_id = :card_id OR card_b_id = :card_id
|
||||
ORDER BY strength DESC, confidence DESC
|
||||
LIMIT :limit
|
||||
"""
|
||||
elif recommendation_type == "evolution":
|
||||
# Get evolutions of this card
|
||||
query = """
|
||||
SELECT evolved_card_id as recommended_card_id,
|
||||
strength,
|
||||
evolution_type,
|
||||
confidence
|
||||
FROM mtg_card_evolution
|
||||
WHERE card_id = :card_id
|
||||
ORDER BY strength DESC, confidence DESC
|
||||
LIMIT :limit
|
||||
"""
|
||||
else:
|
||||
raise HTTPException(status_code=400, detail=f"Invalid recommendation type: {recommendation_type}")
|
||||
|
||||
params = {"card_id": card_id, "limit": limit}
|
||||
|
||||
result = await db.execute(text(query), params)
|
||||
rows = result.fetchall()
|
||||
|
||||
recommendations = []
|
||||
for row in rows:
|
||||
recommendations.append({
|
||||
"recommended_card_id": row[0],
|
||||
"strength": row[1],
|
||||
"type": recommendation_type,
|
||||
"subtype": row[2],
|
||||
"confidence": row[3],
|
||||
})
|
||||
|
||||
await cache_set(cache_key, recommendations, ttl=900)
|
||||
|
||||
return {
|
||||
"cached": False,
|
||||
"results": recommendations,
|
||||
}
|
||||
|
||||
|
||||
@router.get("/search/synergies")
|
||||
async def search_synergies(
|
||||
card_a_id: Optional[int] = Query(None, description="Card A ID"),
|
||||
card_b_id: Optional[int] = Query(None, description="Card B ID"),
|
||||
synergy_type: Optional[str] = Query(None, description="Filter by synergy type"),
|
||||
min_strength: int = Query(1, ge=1, le=5, description="Minimum strength"),
|
||||
min_confidence: float = Query(0.0, ge=0.0, le=1.0, description="Minimum confidence"),
|
||||
limit: int = Query(100, ge=1, le=1000, description="Maximum results"),
|
||||
offset: int = Query(0, ge=0, description="Number of results to skip"),
|
||||
db: AsyncSession = Depends(mtg_get_db),
|
||||
):
|
||||
"""
|
||||
Search synergies with multiple filters.
|
||||
"""
|
||||
cache_key = f"search_synergies:{card_a_id}:{card_b_id}:{synergy_type}:{min_strength}:{min_confidence}:{limit}:{offset}"
|
||||
|
||||
cached = await cache_get(cache_key)
|
||||
if cached:
|
||||
return {"cached": True, "results": cached}
|
||||
|
||||
conditions = []
|
||||
params = {}
|
||||
|
||||
if card_a_id:
|
||||
conditions.append("card_a_id = :card_a_id")
|
||||
params["card_a_id"] = card_a_id
|
||||
|
||||
if card_b_id:
|
||||
conditions.append("card_b_id = :card_b_id")
|
||||
params["card_b_id"] = card_b_id
|
||||
|
||||
if synergy_type:
|
||||
conditions.append("synergy_type = :synergy_type")
|
||||
params["synergy_type"] = synergy_type
|
||||
|
||||
if min_strength:
|
||||
conditions.append("strength >= :min_strength")
|
||||
params["min_strength"] = min_strength
|
||||
|
||||
if min_confidence:
|
||||
conditions.append("confidence >= :min_confidence")
|
||||
params["min_confidence"] = min_confidence
|
||||
|
||||
where_clause = " AND ".join(conditions) if conditions else "TRUE"
|
||||
|
||||
query = f"""
|
||||
SELECT id, card_a_id, card_b_id, synergy_type, strength, notes, confidence
|
||||
FROM mtg_card_synergies
|
||||
WHERE {where_clause}
|
||||
ORDER BY strength DESC, confidence DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
"""
|
||||
params["limit"] = limit
|
||||
params["offset"] = offset
|
||||
|
||||
result = await db.execute(text(query), params)
|
||||
rows = result.fetchall()
|
||||
|
||||
synergies = []
|
||||
for row in rows:
|
||||
synergies.append({
|
||||
"id": row[0],
|
||||
"card_a_id": row[1],
|
||||
"card_b_id": row[2],
|
||||
"synergy_type": row[3],
|
||||
"strength": row[4],
|
||||
"notes": row[5],
|
||||
"confidence": row[6],
|
||||
})
|
||||
|
||||
count_query = f"""
|
||||
SELECT COUNT(*)
|
||||
FROM mtg_card_synergies
|
||||
WHERE {where_clause}
|
||||
"""
|
||||
count_result = await db.execute(text(count_query), params)
|
||||
total = count_result.scalar()
|
||||
|
||||
await cache_set(cache_key, {"synergies": synergies, "total": total}, ttl=600)
|
||||
|
||||
return {
|
||||
"cached": False,
|
||||
"results": synergies,
|
||||
"pagination": {
|
||||
"total": total,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@router.get("/search/counters")
|
||||
async def search_counters(
|
||||
card_a_id: Optional[int] = Query(None, description="Card A ID"),
|
||||
card_b_id: Optional[int] = Query(None, description="Card B ID"),
|
||||
counter_type: Optional[str] = Query(None, description="Filter by counter type"),
|
||||
min_strength: int = Query(1, ge=1, le=5, description="Minimum strength"),
|
||||
min_confidence: float = Query(0.0, ge=0.0, le=1.0, description="Minimum confidence"),
|
||||
limit: int = Query(100, ge=1, le=1000, description="Maximum results"),
|
||||
offset: int = Query(0, ge=0, description="Number of results to skip"),
|
||||
db: AsyncSession = Depends(mtg_get_db),
|
||||
):
|
||||
"""
|
||||
Search counters with multiple filters.
|
||||
"""
|
||||
cache_key = f"search_counters:{card_a_id}:{card_b_id}:{counter_type}:{min_strength}:{min_confidence}:{limit}:{offset}"
|
||||
|
||||
cached = await cache_get(cache_key)
|
||||
if cached:
|
||||
return {"cached": True, "results": cached}
|
||||
|
||||
conditions = []
|
||||
params = {}
|
||||
|
||||
if card_a_id:
|
||||
conditions.append("card_a_id = :card_a_id")
|
||||
params["card_a_id"] = card_a_id
|
||||
|
||||
if card_b_id:
|
||||
conditions.append("card_b_id = :card_b_id")
|
||||
params["card_b_id"] = card_b_id
|
||||
|
||||
if counter_type:
|
||||
conditions.append("counter_type = :counter_type")
|
||||
params["counter_type"] = counter_type
|
||||
|
||||
if min_strength:
|
||||
conditions.append("strength >= :min_strength")
|
||||
params["min_strength"] = min_strength
|
||||
|
||||
if min_confidence:
|
||||
conditions.append("confidence >= :min_confidence")
|
||||
params["min_confidence"] = min_confidence
|
||||
|
||||
where_clause = " AND ".join(conditions) if conditions else "TRUE"
|
||||
|
||||
query = f"""
|
||||
SELECT id, card_a_id, card_b_id, counter_type, strength, notes, confidence
|
||||
FROM mtg_card_counters
|
||||
WHERE {where_clause}
|
||||
ORDER BY strength DESC, confidence DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
"""
|
||||
params["limit"] = limit
|
||||
params["offset"] = offset
|
||||
|
||||
result = await db.execute(text(query), params)
|
||||
rows = result.fetchall()
|
||||
|
||||
counters = []
|
||||
for row in rows:
|
||||
counters.append({
|
||||
"id": row[0],
|
||||
"card_a_id": row[1],
|
||||
"card_b_id": row[2],
|
||||
"counter_type": row[3],
|
||||
"strength": row[4],
|
||||
"notes": row[5],
|
||||
"confidence": row[6],
|
||||
})
|
||||
|
||||
count_query = f"""
|
||||
SELECT COUNT(*)
|
||||
FROM mtg_card_counters
|
||||
WHERE {where_clause}
|
||||
"""
|
||||
count_result = await db.execute(text(count_query), params)
|
||||
total = count_result.scalar()
|
||||
|
||||
await cache_set(cache_key, {"counters": counters, "total": total}, ttl=600)
|
||||
|
||||
return {
|
||||
"cached": False,
|
||||
"results": counters,
|
||||
"pagination": {
|
||||
"total": total,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@router.get("/search/evolutions")
|
||||
async def search_evolutions(
|
||||
card_id: Optional[int] = Query(None, description="Card ID"),
|
||||
evolved_card_id: Optional[int] = Query(None, description="Evolved Card ID"),
|
||||
evolution_type: Optional[str] = Query(None, description="Filter by evolution type"),
|
||||
min_strength: int = Query(1, ge=1, le=5, description="Minimum strength"),
|
||||
min_confidence: float = Query(0.0, ge=0.0, le=1.0, description="Minimum confidence"),
|
||||
limit: int = Query(100, ge=1, le=1000, description="Maximum results"),
|
||||
offset: int = Query(0, ge=0, description="Number of results to skip"),
|
||||
db: AsyncSession = Depends(mtg_get_db),
|
||||
):
|
||||
"""
|
||||
Search evolutions with multiple filters.
|
||||
"""
|
||||
cache_key = f"search_evolutions:{card_id}:{evolved_card_id}:{evolution_type}:{min_strength}:{min_confidence}:{limit}:{offset}"
|
||||
|
||||
cached = await cache_get(cache_key)
|
||||
if cached:
|
||||
return {"cached": True, "results": cached}
|
||||
|
||||
conditions = []
|
||||
params = {}
|
||||
|
||||
if card_id:
|
||||
conditions.append("card_id = :card_id")
|
||||
params["card_id"] = card_id
|
||||
|
||||
if evolved_card_id:
|
||||
conditions.append("evolved_card_id = :evolved_card_id")
|
||||
params["evolved_card_id"] = evolved_card_id
|
||||
|
||||
if evolution_type:
|
||||
conditions.append("evolution_type = :evolution_type")
|
||||
params["evolution_type"] = evolution_type
|
||||
|
||||
if min_strength:
|
||||
conditions.append("strength >= :min_strength")
|
||||
params["min_strength"] = min_strength
|
||||
|
||||
if min_confidence:
|
||||
conditions.append("confidence >= :min_confidence")
|
||||
params["min_confidence"] = min_confidence
|
||||
|
||||
where_clause = " AND ".join(conditions) if conditions else "TRUE"
|
||||
|
||||
query = f"""
|
||||
SELECT id, card_id, evolved_card_id, evolution_type, strength, notes, confidence
|
||||
FROM mtg_card_evolution
|
||||
WHERE {where_clause}
|
||||
ORDER BY strength DESC, confidence DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
"""
|
||||
params["limit"] = limit
|
||||
params["offset"] = offset
|
||||
|
||||
result = await db.execute(text(query), params)
|
||||
rows = result.fetchall()
|
||||
|
||||
evolutions = []
|
||||
for row in rows:
|
||||
evolutions.append({
|
||||
"id": row[0],
|
||||
"card_id": row[1],
|
||||
"evolved_card_id": row[2],
|
||||
"evolution_type": row[3],
|
||||
"strength": row[4],
|
||||
"notes": row[5],
|
||||
"confidence": row[6],
|
||||
})
|
||||
|
||||
count_query = f"""
|
||||
SELECT COUNT(*)
|
||||
FROM mtg_card_evolution
|
||||
WHERE {where_clause}
|
||||
"""
|
||||
count_result = await db.execute(text(count_query), params)
|
||||
total = count_result.scalar()
|
||||
|
||||
await cache_set(cache_key, {"evolutions": evolutions, "total": total}, ttl=600)
|
||||
|
||||
return {
|
||||
"cached": False,
|
||||
"results": evolutions,
|
||||
"pagination": {
|
||||
"total": total,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@router.get("/stats/{card_id}")
|
||||
async def get_card_interaction_stats(
|
||||
card_id: int,
|
||||
db: AsyncSession = Depends(mtg_get_db),
|
||||
):
|
||||
"""
|
||||
Get aggregated interaction statistics for a card.
|
||||
"""
|
||||
cache_key = f"interaction_stats:{card_id}"
|
||||
|
||||
cached = await cache_get(cache_key)
|
||||
if cached:
|
||||
return {"cached": True, "results": cached}
|
||||
|
||||
query = """
|
||||
SELECT
|
||||
card_id,
|
||||
total_synergies,
|
||||
total_counters,
|
||||
total_evolutions,
|
||||
total_synergy_strength,
|
||||
avg_synergy_strength
|
||||
FROM mtg_card_interaction_stats
|
||||
WHERE card_id = :card_id
|
||||
"""
|
||||
params = {"card_id": card_id}
|
||||
|
||||
result = await db.execute(text(query), params)
|
||||
row = result.fetchone()
|
||||
|
||||
if not row:
|
||||
return {
|
||||
"cached": False,
|
||||
"results": {
|
||||
"card_id": card_id,
|
||||
"total_synergies": 0,
|
||||
"total_counters": 0,
|
||||
"total_evolutions": 0,
|
||||
"total_synergy_strength": 0,
|
||||
"avg_synergy_strength": 0,
|
||||
}
|
||||
}
|
||||
|
||||
stats = {
|
||||
"card_id": row[0],
|
||||
"total_synergies": row[1],
|
||||
"total_counters": row[2],
|
||||
"total_evolutions": row[3],
|
||||
"total_synergy_strength": row[4],
|
||||
"avg_synergy_strength": row[5],
|
||||
}
|
||||
|
||||
await cache_set(cache_key, stats, ttl=1800)
|
||||
|
||||
return {
|
||||
"cached": False,
|
||||
"results": stats,
|
||||
}
|
||||
Reference in New Issue
Block a user