Base code

This commit is contained in:
Kunthawat Greethong
2026-01-08 22:39:53 +07:00
parent 697115c61a
commit c35fa52117
2169 changed files with 626670 additions and 0 deletions

View 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)}")