Base code
This commit is contained in:
166
backend/routers/bing_analytics.py
Normal file
166
backend/routers/bing_analytics.py
Normal file
@@ -0,0 +1,166 @@
|
||||
"""
|
||||
Bing Webmaster Analytics API Routes
|
||||
Provides endpoints for accessing Bing Webmaster Tools analytics data.
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from typing import Optional, Dict, Any
|
||||
from datetime import datetime, timedelta
|
||||
from loguru import logger
|
||||
|
||||
from services.integrations.bing_oauth import BingOAuthService
|
||||
from middleware.auth_middleware import get_current_user
|
||||
|
||||
router = APIRouter(prefix="/bing", tags=["Bing Analytics"])
|
||||
|
||||
# Initialize Bing OAuth service
|
||||
bing_service = BingOAuthService()
|
||||
|
||||
@router.get("/query-stats")
|
||||
async def get_query_stats(
|
||||
site_url: str = Query(..., description="The site URL to get query stats for"),
|
||||
start_date: Optional[str] = Query(None, description="Start date in YYYY-MM-DD format"),
|
||||
end_date: Optional[str] = Query(None, description="End date in YYYY-MM-DD format"),
|
||||
page: int = Query(0, description="Page number for pagination"),
|
||||
current_user: Dict[str, Any] = Depends(get_current_user)
|
||||
):
|
||||
"""Get search query statistics for a Bing Webmaster site."""
|
||||
try:
|
||||
user_id = current_user.get("user_id")
|
||||
if not user_id:
|
||||
raise HTTPException(status_code=401, detail="User not authenticated")
|
||||
|
||||
logger.info(f"Getting Bing query stats for user {user_id}, site: {site_url}")
|
||||
|
||||
# Get query stats from Bing service
|
||||
result = bing_service.get_query_stats(
|
||||
user_id=user_id,
|
||||
site_url=site_url,
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
page=page
|
||||
)
|
||||
|
||||
if "error" in result:
|
||||
logger.error(f"Bing query stats error: {result['error']}")
|
||||
raise HTTPException(status_code=400, detail=result["error"])
|
||||
|
||||
logger.info(f"Successfully retrieved Bing query stats for {site_url}")
|
||||
return {
|
||||
"success": True,
|
||||
"data": result,
|
||||
"site_url": site_url,
|
||||
"start_date": start_date,
|
||||
"end_date": end_date,
|
||||
"page": page
|
||||
}
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting Bing query stats: {e}")
|
||||
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
|
||||
|
||||
@router.get("/user-sites")
|
||||
async def get_user_sites(
|
||||
current_user: Dict[str, Any] = Depends(get_current_user)
|
||||
):
|
||||
"""Get list of user's verified sites from Bing Webmaster."""
|
||||
try:
|
||||
user_id = current_user.get("user_id")
|
||||
if not user_id:
|
||||
raise HTTPException(status_code=401, detail="User not authenticated")
|
||||
|
||||
logger.info(f"Getting Bing user sites for user {user_id}")
|
||||
|
||||
# Get user sites from Bing service
|
||||
sites = bing_service.get_user_sites(user_id)
|
||||
|
||||
logger.info(f"Successfully retrieved {len(sites)} Bing sites for user {user_id}")
|
||||
return {
|
||||
"success": True,
|
||||
"sites": sites,
|
||||
"total_sites": len(sites)
|
||||
}
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting Bing user sites: {e}")
|
||||
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
|
||||
|
||||
@router.get("/query-stats/summary")
|
||||
async def get_query_stats_summary(
|
||||
site_url: str = Query(..., description="The site URL to get query stats summary for"),
|
||||
start_date: Optional[str] = Query(None, description="Start date in YYYY-MM-DD format"),
|
||||
end_date: Optional[str] = Query(None, description="End date in YYYY-MM-DD format"),
|
||||
current_user: Dict[str, Any] = Depends(get_current_user)
|
||||
):
|
||||
"""Get summarized query statistics for a Bing Webmaster site."""
|
||||
try:
|
||||
user_id = current_user.get("user_id")
|
||||
if not user_id:
|
||||
raise HTTPException(status_code=401, detail="User not authenticated")
|
||||
|
||||
logger.info(f"Getting Bing query stats summary for user {user_id}, site: {site_url}")
|
||||
|
||||
# Get query stats from Bing service
|
||||
result = bing_service.get_query_stats(
|
||||
user_id=user_id,
|
||||
site_url=site_url,
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
page=0 # Just get first page for summary
|
||||
)
|
||||
|
||||
if "error" in result:
|
||||
logger.error(f"Bing query stats error: {result['error']}")
|
||||
raise HTTPException(status_code=400, detail=result["error"])
|
||||
|
||||
# Extract summary data
|
||||
query_data = result.get('d', {})
|
||||
queries = query_data.get('results', [])
|
||||
|
||||
# Calculate summary statistics
|
||||
total_clicks = sum(query.get('Clicks', 0) for query in queries)
|
||||
total_impressions = sum(query.get('Impressions', 0) for query in queries)
|
||||
total_queries = len(queries)
|
||||
avg_ctr = (total_clicks / total_impressions * 100) if total_impressions > 0 else 0
|
||||
avg_position = sum(query.get('AvgClickPosition', 0) for query in queries) / total_queries if total_queries > 0 else 0
|
||||
|
||||
# Get top queries
|
||||
top_queries = sorted(queries, key=lambda x: x.get('Clicks', 0), reverse=True)[:5]
|
||||
|
||||
summary = {
|
||||
"total_queries": total_queries,
|
||||
"total_clicks": total_clicks,
|
||||
"total_impressions": total_impressions,
|
||||
"average_ctr": round(avg_ctr, 2),
|
||||
"average_position": round(avg_position, 2),
|
||||
"top_queries": [
|
||||
{
|
||||
"query": q.get('Query', ''),
|
||||
"clicks": q.get('Clicks', 0),
|
||||
"impressions": q.get('Impressions', 0),
|
||||
"ctr": round(q.get('Clicks', 0) / q.get('Impressions', 1) * 100, 2),
|
||||
"position": q.get('AvgClickPosition', 0)
|
||||
}
|
||||
for q in top_queries
|
||||
]
|
||||
}
|
||||
|
||||
logger.info(f"Successfully created Bing query stats summary for {site_url}")
|
||||
return {
|
||||
"success": True,
|
||||
"summary": summary,
|
||||
"site_url": site_url,
|
||||
"start_date": start_date,
|
||||
"end_date": end_date,
|
||||
"raw_data": result
|
||||
}
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting Bing query stats summary: {e}")
|
||||
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
|
||||
Reference in New Issue
Block a user